是由 NetScape 提出的著名的安全策略,全部支持 javaScript 的浏览器都使用这个策略。同源策略限制了一个源中加载文本或脚本与来自其它源中资源的交互方式,同源策略是浏览器最核心也最基本的安全功能。html
怎样算跨域呢?前端
浏览器只容许请求当前域的资源,而对其余域的资源表示不信任。可是现代浏览器在安全性和实用性上作出了让步, img/script/style/iframe 等有 src 属性的都容许跨域引用资源。java
这是一个 W3C 标准,全称是“跨域资源共享”(Cross-Origin Resource Sharing),它容许浏览器向跨域服务器发出 XMLHttpRequest 请求,从而解决了 Ajax 只能同源使用的限制。 CORS 须要浏览器和服务器同时支持,可是整个通讯过程,都是浏览器自动完成(IE浏览器不能低于IE10)。json
对于简单请求,浏览器直接发出 CORS 请求。浏览器会自动在头信息(Request Headers)中,添加一个 Origin 字段,来代表本次请求来自哪一个域(Chrome 在非跨域的状况下,也会发送 Origin 字段)。跨域
若是这个源不在许可范围内,服务器会返回一个正常的 HTTP 回应。浏览器发现,这个回应的头信息没有包含 Access-Control-Allow-Origin 字段,就知道出错了,从而抛出一个错误,被 XMLHttpRequest 的 onerror 回调函数捕获。注意,这种错误没法经过状态码识别,由于 HTTP 回应的状态码有多是200。浏览器
PHP 服务端配置示例:缓存
header('Access-Control-Allow-Origin:http://127.0.0.1:80');
设置为 * 表示该数据对任何人可见(可是浏览器将不会发送 Cookie ,即便 xhr 设置了 withCredentials ),若是只但愿特定的地址访问,能够设置为对应的地址。安全
通常基于 HTTP Cookie 的验证身份对于跨域 XMLHttpRequest 请求来讲,浏览器并不会发送对应的身份凭证信息,若是须要带上身份凭证的 XMLHttpRequest 请求,须要作额外的设置。服务器
PHP 服务端示例:cookie
header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Origin:{$_SERVER['HTTP_ORIGIN']}"); // 动态获取请求域。能够先设置一个白名单列表,判断Orign是否在白名单里
前端 Ajax 也要打开 withCredentials 属性,从而向服务器发送 Cookie ,服务端设置 Access-Control-Allow-Credentials:true 来把响应内容返回请求者:
// Jq xhrFields: { withCredentials: true } // 原生 var xhr=new XMLHttpRequest(); xhr.withCredentials=true;
对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为 * 。这是由于请求的首部中携带了 Cookie 信息,若是 Access-Control-Allow-Origin 的值为 * ,请求将会失败。
也就是说 Access-Control-Allow-Credentials 设置为 true 的状况下, Access-Control-Allow-Origin 不能设置为 * 。
Cookie 依然遵循同源政策,只有用服务器域名设置的 Cookie 才会上传,其余域名的 Cookie 并不会上传,且(跨源)原网页代码中的 document.cookie 也没法读取服务器域名下的 Cookie 。
除了上面说的简单请求外都是非简单请求。如:请求方法是 PUT 或 DELETE ;或者 Content-Type 字段的类型是 application/json ;又或者有自定义请求头。
浏览器会先发送 option (预检)请求,要求服务器确承认以这样请求。服务端须要加两个参数设置:
//指定容许其余域名访问 header('Access-Control-Allow-Origin:$_SERVER['HTTP_ORIGIN']') //是否容许后续请求携带认证信息(cookies),该值只能是true,不然不返回 header('Access-Control-Allow-Credentials:true') //预检结果缓存时间 header('Access-Control-Max-Age: 1800') //容许的请求类型 header('Access-Control-Allow-Methods:GET,POST,PUT,POST') //容许的请求头字段 header('Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Accept, Authorization')
预检请求成功以后,浏览器就会进行正常 CORS 请求。
参考:
http://www.ruanyifeng.com/blog/2016/04/cors.html