重新整理:
1.js 发起xhr 只要域名端口不一样就会产生跨域请求。
2.Access-Control-Allow-Credentials 设置true时,Access-Control-Allow-Origin不能设置为*,Access-Control-Allow-Headers也不能随便设置,会影响请求结果失败。
3.请求为application/json 会发送尝试请求OPTIONS,application/x-www-form-urlencoded表单提交模式只会发起post请求。
axios.interceptors.request.use(
config => {
config.headers["Access-Control-Allow-origin"] = "*";
config.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";//无效
return config;
},
err => Promise.reject(err)
);
axios.post( "http://127.0.0.1:12092/IMaterialBatchPhoto/ExecProc", {
params: {"procName":"ToubanMarketingMX","paramslist":["2022春季",11]}
} )
.then( res => {
console.log(res);
} )
.catch( err => {
console.log(err);
} )
结果如图:
发起一个options请求,询问服务器是否允许跨域请求。
大部分跨域问题就出在这里,axios发起option请求,服务端只是通过某些配置时,并不能解决option请求的,比如自定义拦截器,系列化等没有处理options请求,导致 optiongs请求失败。
一般地,自己写个拦截器阻断,判断如果是option请求,强行处理成功。
我以WCF restful为例。
定义拦截器 MessageInspector : IDispatchMessageInspector
重写方法:
public void BeforeSendReply(ref Message reply, object correlationState)
{
#region 处理跨域 Options握手
HttpRequestMessageProperty request = null;
foreach (var value in OperationContext.Current.RequestContext.RequestMessage.Properties.Values)
{
if (value is HttpRequestMessageProperty)
{
request = value as HttpRequestMessageProperty;
break;
}
}
//强行重写options请求成功
if (request.Method == "OPTIONS")
{
HttpResponseMessageProperty response = null;
foreach (var value in reply.Properties.Values)
{
if (value is HttpResponseMessageProperty)
{
response = value as HttpResponseMessageProperty;
break;
}
}
if (response != null)
{ //OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name
response.Headers["Access-Control-Allow-Origin"]= "*";
response.Headers.Add("Access-Control-Allow-Headers", "*");
response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.Headers["Content-Type"]= "application/json;charset=UTF-8";
response.StatusCode = System.Net.HttpStatusCode.OK;
}
}
#endregion
}
JQ发起请求不一样,似乎更先进了,设置crossDomain: true,JQ发的请求居然没有option直接POST进入主题的,这里说的是jquery-3.1.1
$.ajax({
url: url,//此处换成你的服务端地址
type: type,
crossDomain: true, //允许跨域
data: data,
dataType: dataType,
success: function (data) {
alert(data.message);
//alert(successAlert);
},
error: function (err) {
alert(err.message)
//alert(errorAlert);
}
});
总的来说,跨域似乎跨客户端设置关系不是很大的
服务端处理允许跨域即可的,注意处理 options请求
参考: