1、跨域原因 这个不用多解释 无非就是ip+端口 前后端有其中一个不匹配就会跨域。如(S:http://127.0.0.1:81,C:http://127.0.0.1:82)
2、要解决的问题:
2.1、简单post请求后可正常访问,复杂post请求,不能进入后端服务!
2.2、复杂post请求 session丢失!
先给出可运行的解决方案:
3.1、ajax前端代码
t.ajax(t.extend({
type: "post",
dataType: "json",
//运行跨域
crossDomain: true,
//头部授权需要开启 如cookie token
xhrFields: {
withCredentials: true
},
//自定义hander头
beforeSend: function(request) {
request.setRequestHeader('custom-request-type', 'xxxx-ajax');
},
success: function(t) {
},
error: function(e, t) {
}
}, e))
3.2、net web.config
<system.webServer>
<security>
<requestFiltering>
<!--拒绝未列出的谓词 只允许GET POST OPTIONS 方法,OPTIONS在跨域请求时必须-->
<verbs allowUnlisted="false">
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="OPTIONS" allowed="true" />
</verbs>
</requestFiltering>
</security>
<httpProtocol>
<customHeaders>
<!--隐藏服务器信息-->
<remove name="X-Powered-By" />
<!--指定前端跨域域名-->
<add name="Access-Control-Allow-Origin" value="http://127.0.0.1:82"/>
<!--指定handers-->
<add name="Access-Control-Allow-Headers" value="custom-request-type" />
<!--指定允许通过的方法-->
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS"/>
<!--允许客户端携带验证信息-->
<add name="Access-Control-Allow-Credentials" value="true" />
<!--指定本次预检请求的有效期,单位为秒 value=0 表示每次异步请求都发起预检请求-->
<add name="Access-Control-Max-Age" value="3600" />
</customHeaders>
</httpProtocol>
</system.webServer>
上面的操作后,即可解决2.1、2.2所述问题。
其中单独补充说明:浏览器的同源策略,就是出于安全考虑,浏览器会限制从脚本发起的跨域HTTP请求(比如异步请求GET, POST, PUT, DELETE, OPTIONS等等),所以浏览器会向所请求的服务器发起两次请求,第一次是浏览器使用OPTIONS方法发起一个预检请求,如果未添加<add verb="OPTIONS" allowed="true" />或允许通过方法没有它,请求便不会进入服务端。第二次才是真正的异步请求,第一次的预检请求获知服务器是否允许该跨域请求:如果允许,才发起第二次真实的请求;如果不允许,则拦截第二次请求。
可优化处理服务端:
未发布的客户端,请求地址各不相同。便可以把配置文件放到Global.asax.cs中,如下:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Headers.Add("Access-Control-Allow-Origin", Request.Headers.Get("Origin"));
Response.Flush();
}
}