从根源阐述浏览器自发options请求问题

意外碰到了浏览器自发options请求问题,从懵逼到通,仅以此文来对自己的探索做个总结,同时配以另外一个深度篇讲述跨域遇到的问题和解决方式

发起options的理由-Cors

跨域方式: jsonp,  ajax,  cors  发展不再赘述,重点看cors的运行机制

Cors原理阐述:cors是结合浏览器和服务器存在的一种跨域机制,分为简单请求和复杂请求

                         当请求不再是简单请求的时候,浏览器会自发options请求,与服务器通信,带回是否可以跨域的信息,由此开启正                           式调用接口。options请求是浏览器自发进行的,用户并不知觉。

 

服务端的请求方式

请求方式                                                     描述应用场景
Get请求页面,并返回页面内容获取数据,参数一般设置为params
Post大多数用于提交表单或者文件,数据放在请求体中提交数据,参数一般设置为data
Options预检请求,用于查看服务端性能以及是否可以跨域请求预检索(本文重点)
Head类似于Get请求,只不过返回的响应中没有具体内容,用于获取报头不常用
Put从客户端向服务器发送的数据取代定制文档的内容不常用
Delete请求服务端删除指定的页面不常用
Connect把服务器当做跳板,代替客户端去访问其他网页不常用
Trace回显服务器收到的服务器收到的请求,用于测试或诊断不常用

 

Cors

请求类型方式content-type
简单请求Get,Head,Post

 application/x-www-form-urlencoded

 multipart/form-data

 text/xml

复杂请求(需预检)Options,Put,Delete,Connect,Trace非以上三种格式

content-type内涵

本质解析: 

          content-type是Http的实体首部字段,用于表明请求或返回的消息主体是何种格式编码,存在于request-header和response-               header

类型解析: 

1:  application/x-www-form-urlencoded

       浏览器的原生form表单,并且提交的数据按照key1=val1& key2=val2....的方式,同时进行了url转码

2:  multipart/form-data

        常见的post提交数据的方式,并且在form表单里配置属性enctype=“multipart/form-data”

3:    text/xml

       是一种以Http作为传输协议,XML作为编码规范的远程调用模式

4:    application/json

       现在常用的json格式规范

跨域过程

跨域请求

 发起请求的时候浏览器会自动判断是否为简单请求,如果为简单请求,浏览器直接发出cors请求,实际操作则是在发送信息内自动   添加origin字段,表示当前发起请求的源(协议+域名+端口)

GET /cors HTTP/1.1
Origin: [http://api.bob.com](http://api.bob.com/)
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

     PS:User-Agentl: 设备识别信息

服务端响应,返回情况如下

  • 服务端拒绝
        服务端仍会返回一个正常的状态码,有可能为200,但是头部信息不存在Access-Control-Allow-Origin字段。此时浏览器感应到收到了服务端的拒绝信息, 从而抛出一个错误,被XMLHttpRequest的onerror的回调函数捕获
     
  • 服务端表示同意
        如果origin指定的域名在许可范围内,则会在响应的头部信息内添加以下字段
    Access-Control-Allow-Origin: [http://api.bob.com](http://api.bob.com/)
    Access-Control-Allow-Credentials: true
    Access-Control-Expose-Headers: FooBar
    Content-Type: text/html; charset=utf-8
  1.  Access-Control-Allow-Origin 字段
         字段必选。 表示服务端允许跨域访问的源,或者指定,或者为‘*’,表示全部通过
     
  2. Access-Contaol-Allow-Credentials
          字段可选。表示服务端允许该源携带cookie。cookie可以放在请求头中,也可以放在请求体中,服务端设置该属性为false,则明确表示不允许在头部携带。
     

     3: Access-Control-Expose-Headers
        字段可选。浏览器在服务端的响应中,通过XMLHttpRequest对象只能获取到6个固定的字段( Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma )如果需要获取到其他字段的信息,必须在该属性内指定。如上图,指定需要获取FootBar字段内容。

        PS:  当请求头部需要携带cookie,设置withCredentials或include:true时,服务端返回的Access-Control-Allow-Origin不能再为‘*’,必须是请求头发出的Oringin

预检请求

预检请求会在正常的cors请求之前,发送预检请求,得到服务端对于跨域是否同意的回应,如果服务端同意,则开始正常的cors请求发送。

预检请求头部信息:

 

OPTIONS /cors HTTP/1.1
Origin: [http://api.bob.com](http://api.bob.com/)
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-HeaderHost: api.alice.com
Accept-Language: en-USConnection: keep-alive
User-Agent: Mozilla/5.0...


所发送的字段:

    Access-Control-Request-Method:  指定请求方式
    Access-Control-Request-Headers: 指定头部携带的参数字段信息
    Origin:指定源(协议+域名+端口)

服务端返回

PUT /cors HTTP/1.1
Origin: [http://api.bob.com](http://api.bob.com/)
Host: api.alice.com
X-Custom-Header: value
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

   服务端收到预检请求后,检查字段信息,后予以返回

   字段解释与简单请求一样,不再赘述。

预检请求后

    之后,浏览器每次调接口的方式为简单请求方式,每次携带origin,并且每次收到服务端的Access-Control-Allow-Origin,根据返回的状态码进行判断以及取用信息.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值