CORS 跨域资源访问

来源:互联网 发布:自学javascript 编辑:程序博客网 时间:2024/04/25 15:30

参考:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
https://www.w3.org/TR/cors/
http://www.ruanyifeng.com/blog/2016/04/cors.html

一. 概述

CORS(Cross-Origin Resource Sharing,跨域资源访问):需要访问跨域资源或需要发起跨域AJAX时,可以在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用。跨域访问控制在 Web 应用服务端进行,安全。

CORS需要浏览器服务器同时支持。IE10以下浏览器不支持CORS。

服务器通过 HTTP 首部字段声明哪些源站有权限访问哪些资源。

二. 简单请求和非简单请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

1. 简单请求

简单请求:不会触发 CORS 预检请求的请求。对于简单请求,浏览器直接发出CORS请求。
简单请求必须满足:

(1) 请求方法是以下三种方法之一:- HEAD- GET- POST(2)HTTP的头信息不超出以下几种字段:- Accept- Accept-Language- Content-Language- Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

浏览器发现请求是跨域AJAX请求时,自动在头部加上 Origin 字段,表明请求来源。Origin: http://xx.com
服务器收到请求后:

  • 如果 Origin 指定的源,不在许可范围内,服务器会返回一个正常的HTTP响应(状态码可能是200),但这个响应的头信息没有包含Access-Control-Allow-Origin字段,浏览器因此知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。
  • 如果 Origin 指定的源,在许可范围内,需要返回 HTTP 头信息:Access-Control-Allow-Origin,指明服务器允许哪些源访问。如果要允许多个源访问,需要配置Nginx()。
    • Access-Control-Allow-Origin: null 不允许所有源跨源访问
    • Access-Control-Allow-Origin: * 允许所有源访问
    • Access-Control-Allow-Origin: http://yy.com 只允许http://yy.com访问

2. 非简单请求

1. 需预检的请求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求:

OPTIONS /resources/ HTTP/1.1Origin: http://foo.exampleAccess-Control-Request-Method: POSTAccess-Control-Request-Headers: X-PINGOTHER, Content-TypeHTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://foo.exampleAccess-Control-Allow-Methods: POST, GET, OPTIONSAccess-Control-Allow-Headers: X-PINGOTHER, Content-TypeAccess-Control-Max-Age: 86400

2. 预检请求完成之后,发送实际请求:

POST /resources/post-here/ HTTP/1.1X-PINGOTHER: pingpongContent-Type: text/xml; charset=UTF-8[data...]HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:40 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://foo.example

3. 附带身份凭证的请求

CORS 可以基于 HTTP cookies 和 HTTP 认证信息发送身份凭证。
默认不发送。必须手动将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者
对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。

4. CORS常用的HTTP首部字段解释:

字段 由谁设置 作用 Origin 浏览器 指明简单请求或预检请求从哪个源发起,不管是否跨域都会设置 Access-Control-Request-Method 浏览器 在预检请求中出现,用于通知服务器在真正的请求中会采用哪种
HTTP 方法。因为预检请求所使用的方法总是 OPTIONS ,与实际请求
所使用的方法不一样,所以这个首部是必要的。 Access-Control-Request-Headers 浏览器 在预检请求中出现,通知服务器在真正的请求中会采用哪些请求首部。 Access-Control-Allow-Origin 服务器 必传,指明资源可以被哪些跨域的源访问。它的值要么是请求时Origin字段
的值,要么是一个*,表示接受任意域名的请求。 Access-Control-Allow-Credentials 服务器 是否允许浏览器读取response的内容。当用在对preflight预检请求的响应中
时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求
不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,
并且浏览器也不会将相应内容返回给网页。 Access-Control-Expose-Headers 服务器 默认只有6种简单响应首部可以暴露给外部:Cache-Control、
Content-Language、Content-Type、Expires、Last-Modified、Pragma。
如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
可指定多个响应首部
Access-Control-Expose-Headers: Content-Length, X-Rev Access-Control-Max-Age 服务器 表示预检请求的返回结果(即 Access-Control-Allow-Methods 和
Access-Control-Allow-Headers 提供的信息) 可以被缓存多久。单位是秒。
不同浏览器的上限和默认值不一样。如果值为 -1,则表示禁用缓存 Access-Control-Allow-Methods 服务器 在预检请求中,其指明了实际请求所允许使用的 HTTP 方法 Access-Control-Allow-Headers 服务器 在预检请求中,指明了实际请求中允许携带的首部字段
原创粉丝点击