谈谈CORS那点事

前端开发过程当中经常须要进行跨域请求 说跨域 有个名词来简单了解下 "同源策略"html

同源策略:限制从一个源加载的文档或脚本如何与来自另外一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。前端

若是协议,端口(若是指定了一个)和域名对于两个页面是相同的,则两个页面具备相同的源。api

下表给出了相对baidu.com/dir/page.ht…:跨域

  1. (同协议 同域名) baidu.com/dir/page1.h… 同 源
  2. (不一样协议) baidu.com/dir/page1.h… 不一样源
  3. (不一样端口) baidu.com:81/dir/page1.h… 不一样源
  4. (不一样域名) baidu2.com/dir/page.ht… 不一样源

跨域就跟在本身(同源)的家 同样想干啥就干啥 能够别人家(不一样源)就不行了
这时候我就想要访问不一样源的 以往的干法是
JSONP是能够实现的 可是有几个很差的地方浏览器

  1. JSONP只能实现GET请求
  2. JSONP被老的浏览器支持

这个时候cors出现了
CORS:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,容许网页从不一样的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来肯定是否容许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地容许全部这些的要求来讲更加安全。安全

因此按照这么说 这CORS就是一种规范 只有基于这个规范 按照规矩来就能够实现不一样源之间资源访问bash

各主流的浏览器都会对动态的跨域请求进行特殊的验证处理。验证处理分为简单请求验证处理和预先请求验证处理。服务器

简单请求:
当请求同时知足下面两个条件时候cookie

请求方法是下列之一:网络

  • 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 详解

相关文章
相关标签/搜索