前端开发过程中常常需要进行跨域请求 说跨域 有个名词来简单了解下 "同源策略"
同源策略:限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。
如果协议,端口(如果指定了一个)和域名对于两个页面是相同的,则两个页面具有相同的源。
下表给出了相对baidu.com/dir/page.ht…:
- (同协议 同域名) baidu.com/dir/page1.h… 同 源
- (不同协议) baidu.com/dir/page1.h… 不同源
- (不同端口) baidu.com:81/dir/page1.h… 不同源
- (不同域名) baidu2.com/dir/page.ht… 不同源
跨域就跟在自己(同源)的家 一样想干啥就干啥 可以别人家(不同源)就不行了
这时候我就想要访问不同源的 以往的干法是
JSONP是可以实现的 但是有几个不好的地方
- JSONP只能实现GET请求
- JSONP被老的浏览器支持
这个时候cors出现了
CORS:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。
所以按照这么说 这CORS就是一种规范 只有基于这个规范 按照规矩来就可以实现不同源之间资源访问
各主流的浏览器都会对动态的跨域请求进行特殊的验证处理。验证处理分为简单请求验证处理和预先请求验证处理。
简单请求:
当请求同时满足下面两个条件时候
请求方法是下列之一:
- GET
- HEAD
- POST
请求头中的Content-Type请求头的值是下列之一:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
简单请求时候 浏览器会直接发送跨域请求在请求头中携带Origin的header表明这是一个跨域的请求。服务器端接到请求后,会根据自己的跨域规则,通过Access-Control-Allow-Origin和Access-Control-Allow-Methods响应头,来返回验证结果。
Access-Control-Allow-Origin: http://XXX.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8复制代码
这里是允许访问后服务器响应
来解释下
- Access-Control-Allow-Origin: 要么指定 origin值 要么就是* 表示接受任意域名请求
- Access-Control-Allow-Credentials: 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
预先请求
当请求同时满足下面两个条件时候
请求方法不是下列之一:
- GET
- HEAD
- POST
请求头中的Content-Type请求头的值不是下列之一:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
预先请求 浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
下面是预先请求的HTTP头信息
OPTIONS /cors HTTP/1.1
Origin: http://xxx.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...复制代码
"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。
上面预先请求中
- Access-Control-Request-Method: 表示请求的用到那个HTTP方法
- Access-Control-Request-Headers:该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。
下面是预先请求响应
Access-Control-Allow-Origin: http://xxx.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header复制代码
- Access-Control-Allow-Origin:表示xxx.com可以请求数据。该字段也可以设为星号,表示同意任意跨源请求。
一旦服务器通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。
参考链接: 跨域资源共享 CORS 详解