zoukankan      html  css  js  c++  java
  • CORS(cross-origin-resource-sharing)跨源资源共享

    其实就是跨域请求。我们知道XHR只能访问同一个域中的资源,这是浏览器的安全策略所限制,但是开发中合理的跨域请求是必须的。CORS是W3的一个工作草案,基本思想就是:使用自定义的HTTP头部让浏览器与服务器沟通,决定响应成功或失败。

    CORS需要浏览器和服务器同时支持,所有浏览器都支持该功能,IE浏览器在IE10以上支持。

    CORS跟同源AJAX请求差别不大,主要是浏览器发现Ajax跨域请求时候,自动添加一些附加的头部信息,有时多一次附加的OPTIONS预检查请求,但用户不会感知。

    (闲话:实际项目中经常遇到Access-Control-Allow-Origin报错,network里面请求数据时候会多请求一次methods为options方法的请求,它返回200后才真正再去请求一次真正的接口请求,这都是请求跨域时候的表现)

    Important Part:CORS将请求分成两大类,simple request(简单请求)和not-so-simple request(非简单请求)

    简单请求的请求方法是:HEAD GET POST其中之一

    头部信息不超过下面几种字段:

    Accept

    Accept-Language

    Content-Language

    Last-Event-ID

    Content-Type:application/x-www-form-urlencoded,multipart/form-data,text/plain

    不是简单请求的就是复杂请求了。

    浏览器处理简单请求步骤:

    直接发起CORS请求,在request header里面添加origin字段源Url(协议+域名+端口号),如果不在许可范围内部,服务器也是返回正常的HTTP response,但是response header里面没有包含Access-Control-Allow-Origin字段,console控制台报错,被浏览器的XHR对象的onerror回调捕获,此时的HTTP返回码可能是200。

    Origin: http://www.nczonline.net

    服务器认为该请求可以接受,response Header里面就会返回Access-Control-Allow-Origin返回相同的源信息地址。

    Access-Control-Allow-Origin: http://www.nczonline.net

    Access-Control-Allow-Credentials:true    //是否允许发送Cookie

    Access-Control-Expost-Headers:FooBar  //获取request header里面额外的字段值

    Content-Type:text/html;charset=utf-8

    如果没有origin信息或者信息不匹配,那么浏览器就驳回请求,浏览器的请求和响应都不包含cookie信息。

    Question:为什么CORS跨域请求和响应默认不包含cookie信息?

    Answer:cookie是同源共享的,既然你都跨域了,就不能使用不同域的cookie信息了。

    —————————————————————————————————————

    Preflighted Requests(预检请求):

    比如非简单请求:PUT,DELETE或者Content-Type是application/json类型的请求。在正式请求之前增加一次HTTP查询请求,称为”预检请求“。

    OPTIONS /cors HTTP/1.1
    Origin: http://api.bob.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...

    上面是预检请求的HTTP requset Header参数,可以看出请求方法是OPTIONS,关键字Origin请求来自哪个源地址,Access-Control-Request-Method:请求方法,Access-Control-Request-Headers:逗号分隔的字符串,浏览器额外附加的头部信息。

    服务器收到预检请求后,检查origin,Access-Control-Request-Method和Access-Control-Request-Headers字段后,确认可以跨域,就返回:

    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 01:15:39 GMT
    Server: Apache/2.0.61 (Unix)
    Access-Control-Allow-Origin: http://api.bob.com
    Access-Control-Allow-Methods: GET, POST, PUT
    Access-Control-Allow-Headers: X-Custom-Header
    Content-Type: text/html; charset=utf-8
    Content-Encoding: gzip
    Content-Length: 0
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Content-Type: text/plain

    Access-Control-Allow-Origin可以设为*,表示同意任意跨源请求。

    __________________________________________________________________

    一旦服务器通过了预检请求,以后每次的正常CORS请求,跟简单请求一样,有Origin头部信息字段,服务器的response header里面会有

    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 01:15:39 GMT
    Server: Apache/2.0.61 (Unix)
    Access-Control-Allow-Origin: http://api.bob.com
    Access-Control-Allow-Methods: GET, POST, PUT
    Access-Control-Allow-Headers: X-Custom-Header
    Content-Type: text/html; charset=utf-8
    Content-Encoding: gzip
    Content-Length: 0
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Content-Type: text/plain

    头部信息字段。

    如果是非简单请求的话,预检之后的response header里面必包含Access-Control-Allow-Origin头部信息。

    ————————————————————————————————————

    CORS会通过预请求的透明服务器验证(透明是指封闭不可见的)机制支持开发者使用自定义头部,GET或POST之外的方法,不同类型的主体内容,预检请求发送的是OPTIONS方法,头部信息包含:

    Origin

    Access-Control-Request-Method

    Access-Control-Request-Headers

    发送请求后,OPTIONS预检请求结束,再次进行真正的Response响应请求。

    跨域请求默认是不带凭证:cookie,HTTP认证和SSL证明的。但是可以通过设置:withCredentials属性为true,指定某个请求应该发送凭证,然后服务器接受请求后,Response Header里面会返回:

    Access-Control-Allow-Credentials:true

    各个浏览器对CORS的支持程度不同,但是都支持简单请求,可以通过检查是否存在withCredentials属性,IE的XDR跟XHR类似,实现安全可靠的跨域通信。所以可以先检测withCredentials属性,再检测XDR对象是否存在,就可以兼顾所有浏览器了。

    其他跨域技术:

    图像Ping:利用img标签的src属性,进行GET请求访问,不能得到服务器的返回。适合单向通信。

    JSONP:利用script标签的src属性,动态生成js脚本,执行服务器返回的js脚本中的带有JSON参数的回调函数。可以通过拿到响应参数自执行回调函数,简单有用。

     ——————————————————————————————————————————

    CORS和JSONP使用目的相同,但是比JSONP更加强大,CORS主要是服务端配置好后,浏览器根据服务端配置的自定义头部和提供的可以进行的CORS的方法来进行跨域操作

    JSONP只支持GET请求,CORS支持所有类型的HTTP请求。

    【完】

    时光荏苒,如白驹过隙。
    岁月如斯,然赤心如故。 

  • 相关阅读:
    文本框输入限制 [大全]
    JavaScript关于window.open()应用
    你还敢使用window.open弹广告吗?
    在HTML网页中插入ActiveX控件
    XMLDOC的常用方法和属性
    细说HTML元素的ID和Name属性的区别
    常用的40个网站制作技巧
    激活 ActiveX 控件
    laravel 配置 elasticsearch
    mac上运行ls 命名查看做面文件的出现“Operation not permitted”错误
  • 原文地址:https://www.cnblogs.com/tangjiao/p/9985396.html
Copyright © 2011-2022 走看看