Chrome浏览器100.0.4896.127正式版
最近在做web需求时,遇到了一个跨域的问题:
浏览器有一个cookie,这个cookie的domain是.rocky.com
,path是/
。
网页域名是 www.rocky.com
,网页会使用ajax请求sub.rocky.com
域名下的一个接口获取数据,奇怪的是,在请求ajax接口时浏览器没有在请求头里带上cookie。
最后通过网上查资料得知,原来这个ajax请求跨域了,原因是接口域名(sub.rocky.com
)跟网页域名( www.rocky.com
)不一样。
之前我天真的以为,只要主域名相同就不算跨域,其实是错误的。
而我们使用的跨域方式是CORS,这种跨域方式默认情况下是不携带cookie的,于是就有了上面的问题。如果想要携带cookie,需要在js代码做下配置,下面以jquery为例:
$.ajax({
url: "http://sub.rocky.com/demo/jquery_qrcode/api.php",
type: "get",
xhrFields: {
withCredentials: true
},
success: function () {
console.log("请求成功");
}
});
需要加上 withCredentials: true
这一个配置。但是,将withCredentials
设置为true
后,后端的接口必须要返回Access-Control-Allow-Credentials: true
的响应头,而且access-control-allow-origin
响应头的值不能为*
,需要改为网页的域名,在我这个例子中是http://www.rocky.com
:
Access-Control-Allow-Credentials: true
access-control-allow-origin: http://www.rocky.com
如果access-control-allow-origin
的值是*
的话,浏览器会报错:
Access to XMLHttpRequest at 'http://sub.rocky.com/demo/jquery_qrcode/api.php' from origin 'http://www.rocky.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
如果Access-Control-Allow-Credentials
不返回true
,浏览器会报错:
Access to XMLHttpRequest at 'http://sub.rocky.com/demo/jquery_qrcode/api.php' from origin 'http://www.rocky.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
经过上面这些处理后,浏览器发起ajax请求终于会带上cookie了~
除了上面这种处理方式,还有一种更简单的方法,就是使用JSONP
跨域方式,不使用CORS
。下面以jquery为例:
$.ajax({
url: "http://sub.rocky.com/demo/jquery_qrcode/api.php",
type: "get",
dataType: "jsonp", // 使用jsonp跨域方式
success: function () {
console.log("请求成功");
}
});
将dataType
设置为jsonp
就可以,就这么简单,后端接口的响应头不需要改动。
但JSONP
跨域方式有一定的限制,就是只支持GET
请求方法,后端接口也要支持JSONP
的callback参数才行。