CORS

作者: 一蓑烟雨任平生_cui | 来源:发表于2020-06-09 18:16 被阅读0次

由于浏览器同源策略(协议、域名、端口)的限制,当浏览器向跨源服务器发起请求时,会出现跨域。

解决跨域的方式有多种,比如jsonp、CORS、Iframe、nginx正、反向代理等。

本文着重介绍CORS。

介绍:

CORS全称是跨域资源共享。需要浏览器和服务器的同时支持。目前所有浏览器都支持,IE需要10以上。

整个通信过程都是浏览器自动完成的,前端开发者不需要做任何设置,关键在于服务器端。

当浏览器发现请求跨域时,就会自动添加一些头部信息,有时会多出一次请求(预检请求),对用户是无感知的。

请求方式

CORS的请求方式有两种,简单请求和非简单请求(需要预检请求)。

1、简单请求

条件:

同时符合以下两个条件为简单请求:

  1. 请求方式
    • GET
    • POST
    • HEAD(只获取报文首部)
  2. 除了浏览器自己在Http头上加的信息(如Host、Connection、User-Agent等)之外,开发者只能加下列字段:
    • Accept
    • Accept-Language
    • Content-Language
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
    • Content-Type 值仅限于三个之一(text/plain、multipart/form-data、application/x-www-form-urlencoded)
流程:

当浏览器发现是跨源请求时,会自动在头部增加Origin字段,用来说明请求源(协议、域名、端口),服务器会根据该字段值决定是否允许请求。

简单请求request头部信息

如果Origin不在服务器的允许的范围,服务器会返回正常的HTTP响应,但响应头中如果不包含Access-Control-Allow-Origin字段,浏览器发现没有该字段便会抛出错误。需要注意的是,这种错误无法通过状态码识别,因为HTTP响应的状态码有可能是200。

如果Origin在允许的范围内,服务器会在响应头中多出以下字段:

  1. Access-Control-Allow-Origin:必选。值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
  2. Access-Control-Allow-Credentials,可选。值为boolean, 表示是否允许浏览器发送cookie,如果不需要,不设置该字段即可。如果要发送,还需要服务器同意,响应头设置Access-Control-Allow-Credentials: true,同时ajax对象设置该属性ajax.withCredentials = false
  3. Access-Control-Expose-Headers,可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
简单请求response头信息

注意: 如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。

非简单请求(需预检请求)

所谓非简单请求是对服务器有特殊要求的请求,比如:

请求方法是:

  1. PUT 传输文件
  2. DELETE 删除文件
  3. CONNECT 要求用隧道协议连接代理
  4. OPTIONS 询问支持的方法
  5. TRACE 路径追踪

Content-Type 字段的类型是application/json

或包含自定义请求头。

非简单请求会在正式通信之前,增加一次HTTP查询请求,称为“预检请求”。

流程:

预检请求必须首先使用Options方式发起请求,获取当前的Origin是否在服务器允许的范围,以及支持的请求方式等。

请求头中除了设置Oirgin字段,还需两个字段:

  1. Access-Control-Request-Method:必选,告诉服务器实际请求将使用的请求方式
  2. Access-Control-Request-Headers:可选,值为逗号分割的字符串,告诉服务器实际请求将携带两个自定义头信息
预检请求头

当服务器收到预检请求后,检查了OriginAccess-Control-Request-MethodAccess-Control-Request-Headers 字段以后确认是否允许跨源请求,如果有一项不满足则不允许跨源请求,浏览器会在控制台抛出错误。如果都满足,预检请求的响应头中会包含以下字段:

  1. Access-Control-Allow-Origin:必选,值为请求头中的Origin
  2. Access-Control-Allow-Methods:必选,值为逗号分隔的字符串,表示允许跨域请求的请求方式
  3. Access-Control-Allow-Credentials:可选,值为boolean, 表示是否允许浏览器发送cookie,详情同简单请求
  4. Access-Control-Allow-Headers:可选, 允许跨域请求额外发送的header字段
  5. Access-Control-Max-Age:可选,预检请求的有效时间。在有效时间内,浏览器无须为同一请求再次发起预检请求。需要注意的是,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。
预检响应头

服务器通过了“预检”请求以后,就可以发起实际请求了,每次请求都会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。

相关文章

  • 如何处理浏览器的跨域问题

    第一种方式 CORS 首先你需要阅读CORS,首先你需要阅读CORS,首先你需要阅读CORS,重要的事情说3遍 当...

  • Express: 启用 cors

    我的自建博客上的文章原地址:Express: 启用 cors 什么是 CORS CORS ([Cross-Orig...

  • express 解决跨域

    使用cors中间件解决跨域问题 npm install cors 安装中间件 const cors = requ...

  • 跨域

    1、Json jsonp 只能支持 get 请求; 2、cors cors 可以支持多种请求。cors 并不需要前...

  • 跨域【详解】

    本篇有四种方法跨域:CORS、JSONP、降域、window.postMessage() 1. CORS CORS...

  • egg

    一 、egg.js之解决跨域问题(egg-cors) 下载 egg-cors 包npm i egg-cors --...

  • express解决跨域问题

    有以下2种解决办法: 第一种,使用cors插件 先安装cors插件 npm install cors --save...

  • 初探CORS

    这篇博客的目的是探究一下CORS前后端的实现 CORS是什么? CORS全拼是Cross-Origin Resou...

  • Java Web前后端分离中CORS配置及OPTIONS请求优化

    Java Web前后端分离中CORS配置及OPTIONS请求优化 0x00 CORS 概述 跨域资源共享(CORS...

  • 使用Node.js处理CORS

    介绍 在本文中,我们将研究什么是CORS,如何使用Express配置CORS,以及如何根据需要定制CORS中间件。...

网友评论

    本文标题:CORS

    本文链接:https://www.haomeiwen.com/subject/khdetktx.html