CORS跨域不能携带cookie的问题

环境

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参数才行。

你可能感兴趣的:(其它,PHP,跨域,CORS,cookie)