正文
什么是跨域请求,跨域的产生来源于现代浏览器所通用的‘同源策略’,所谓同源策略,是指只有在地址的:协议名、域名、端口名, 均一样的情况下,才允许访问相同的cookie、localStorage或是发送Ajax请求等等。若在不同源的情况下访问,就称为跨域。
浏览器出于安全考虑,并不是所有域名都可以直接访问。浏览器在发起任意的请求之前, 浏览器会判断目标的url是不是和当前网站是来自相同的域名,相同则一般认为是安全的, 不同则被认为是跨域,此种请求就是跨域请求,它默认是不可信、不安全的。 (当然,如果不是由浏览器发出的请求,那么自然不是浏览器的责任,比如ddos,就不属于跨域请求的范畴了)
同源策略分为以下两种:
- DOM同源策略:禁止对不同源页面DOM进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
- XmlHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。 只要协议、域名、端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作。
情况一
一般如果前端只是纯粹的获取后端数据,后端只要允许跨域访问就可以了。 PHP设置header头:
header("Access-Control-Allow-Origin: *");
也可以设置为指定域名访问。
情况二
后端要求前端传递自定义header头信息。
后端示例:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: jwt");
前端示例:
$.ajax({
type: "GET",
url: "http://test.host/190304/index.php",
headers: {
'jwt':'123'
},
success: function(data) {
console.log(data);
}
});
前端会有两次请求,第一次嗅探后端是否支持jwt这个自定义头信息,返回允许,第二次才带上jwt这个头信息去获取后端数据。
如果是JQuery,后端需要前端带上其他header信息,前端需要设置crossDomain为true,:
$.ajax({
type: "GET",
url: "http://test.host/190304/",
crossDomain: true,
success: function(data) {
console.log(data);
}
});
情况三
如果牵扯到认证,可以用JWT方式。JWT比较适合的场景是多个服务端用同一个JWT通信,可以简化认证的复杂性。 JWT发现的缺点有:有效期限制(过了这个时间就需要重新去获取JWT认证信息)、 跨域访问,如果是header带上JWT信息,每次都会有两次请求(第一次获取是否允许带这个JWT认证信息头, 第二次才是带上这个JWT认证信息头获取数据),比较浪费资源。
比较合理的方式是cookie带上JWT认证信息,这样就可以避免两次请求,但是如果是cookie方式认证, 那就完全没有必要用JWT了,用JWT只是多此一举,cookie中本来就可以设置加密的认证信息, 而且每次去后端访问都会更新cookie中的认证信息有效时长,也避免了JWT有效期限制的问题。
前后端分离后,后端要求cookie交互,后端需要设置:
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Origin: http://ceshi.host");
Access-Control-Allow-Credentials设置为true后,Access-Control-Allow-Origin要写具体域名,否则不支持。
如果后端支持多个域名可跨域访问:
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = array(
'http://ceshi1.com',
'http://ceshi2.com'
);
if (in_array($origin, $allow_origin)) {
header('Access-Control-Allow-Origin:' .$origin);
}
前端如果是JQuery:
$.ajax({
type: "GET",
url: "http://test.host/190304/",
xhrFields: {
withCredentials: true
},
success: function(data) {
console.log(data);
}
});
withCredentials: true
携带跨域cookie
这样后端可以设置cookie,前端访问后端时也会把cookie带上。
参考资料
https://www.cnblogs.com/nuccch/p/7875189.html
https://blog.csdn.net/z69183787/article/details/78954325
https://blog.csdn.net/thc1987/article/details/54572272
https://blog.csdn.net/Zsigner/article/details/81159731
http://www.runoob.com/w3cnote/php-ajax-cross-border.html
HTTP访问控制(CORS) https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
Cross-Origin Resource Sharing协议介绍 https://www.cnblogs.com/shanyou/archive/2012/09/16/2687907.html
JWT https://blog.csdn.net/weixin_41153791/article/details/82291144