浏览器同源策略导致不能加载执行其他网站的脚本,这是互联网安全的一部分。跨域之后ajax请求可以发出,但浏览器在接收前会对其来源进行检查,如果是不跨域,直接加载数据;如果跨域,会出现著名的No 'Access-Control-Allow-Origin' header is present on the requested resource
。以下总结一些常用的HTTP跨域解决方案。
常见的跨域都需要后端支持,跨域记得带上http头信息Access-Control-Allow-Origin
跨域拦截,并不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。
利用浏览器script标签不跨域特点,使用get请求到目标api,再通过目标api返回callbackName(data)方式执行js代码。特点:
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参并指定回调执行函数为onBack
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);
// 回调执行函数
function onBack(res) {
alert(JSON.stringify(res));
}
// 服务端api返回
onBack({"status": true, "user": "admin"})
跨域资源共享(Cross-origin resource sharing) 是一种机制,它使用额外的 HTTP 头
来告诉浏览器 让运行在一个 origin 上的Web应用被准许访问来自不同源服务器上的指定的资源。特点:
在头信息之中,增加一个Origin字段
。说明本次请求来自哪个域(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求,响应返回Access-Control-Allow-Origin字段
。
Origin
通用Access-Control-Allow-Origin
通用。如果是需要发送附带身份凭证(如cookies)的请求(前端代码需要设置:xhr.withCredentials=true)
Access-Control-Allow-Credentials
:服务器响应需要设置该字段为true,浏览器才会把内容给请求的发送者。为安全性考虑,当响应返回Access-Control-Allow-Credentials:true时,Access-Control-Allow-Origin必须指定具体的Origin,而不是通配符“*”
规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法,浏览器必须首先使用 Method: OPTIONS
发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。
Origin
简单/非简单CORS通用:预检请求或实际请求的源站Access-Control-Allow-Origin
简单/非简单CORS通用: 指定了允许访问该资源的外域 URI大多数浏览器不支持针对于预检请求的重定向。如果一个预检请求发生了重定向,浏览器将报告错误