CORS 跨域访问

跨域
当域名A(http://domain.example)的某web 应用程序中通过标签引入了域名B(http://domainb.foo)站点的某图片资源,域名A的web服务器就会导致浏览器发起一个跨站的HTTP请求。
出于安全考虑,浏览器会限制脚本中发起的跨站请求。比如使用XMLHttpRequest 对象发起的HTTP 请求就必须遵守 同源策略跨域请求并非浏览器限制发起跨站请求,而是请求可以正常发起,但是返回结果会被浏览器拦截。

cors 跨域访问
cors全称“跨域资源共享”,它允许浏览器向跨源服务器发出XMLHTTPRequest 请求,从而克服AJAX只能同源使用的限制。
cors通过新增一系列HTTP头,让服务器能够声明哪些来源可以通过浏览器访问服务器上的资源,对于那些可能会对服务器数据造成破坏性影响的HTTP请求方法,标准要求浏览器必须先以OPTIONS请求方式发送一个预请求,从而获知服务器端对跨源请求所至此的HTTP方法。确认服务器允许该跨源请求的情况下,以实际的HTTP请求方法发送那个真正的请求。

cors 跨域分两种方式

简单请求
简单请求是指:

只使用GET, HEAD, 或者POST请求方法
若使用POST方法则数据类型(Content-Type)只能是application/x-www-form-urlencoded,multipart/form-data 或text/plain中的一种
不会使用自定义请求头(类似与X-Modified这种)

以下为一个简单请求例子,浏览器发现这个AJAX跨源请求是一个简单请求,就自动在头信息中添加Origin字段

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

Origin字段说明本次请求来自哪个源(协议+域名+端口)。服务器根据这个值,决定是否同意这次请求。
如果Origin指定的源不在许可范围之内,服务器会返回一个正常的HTTP相应 浏览器发现这个回应的头信息没有包含Access-Control-Allow-Origin 字段,就知道出错了,从而抛出一个错误。
如果Origin指定的域名在许可范围之内,服务器返回响应,或多出几个头信息字段

Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

若Access-Control-Allow-Origin: http://foo.example则只有http://foo.example允许跨源访问该服务器
Access-Control-Allow-Credentials: True 是可选值2,表示允许发送cookie,默认情况下浏览器不允许发送cookie,布尔值设置为True后cookie包含在请求中,发送给服务器。
cors默认不发送cookie信息,要发送cookie除服务器设置Access-Control-Allow-Credentials: true外,需AJAX开发者打开withCredentials 属性。

* 非简单请求 *
非简单请求,只对服务器有特殊要求的请求,如请求方法为PUT,DELETE 或者Content-Type字段为application/json
非简单请求正式请求前,会额外发送一次OPTIONS请求,称为预请求* (预请求由浏览器自动检测发起) *
浏览器先询问服务器当前域是否在服务器许可名单中,以及可以使用哪些HTTP方法和允许的头字段。只有得到肯定答复,浏览器才发出正式的XMLHttpRequest请求,否则就报错。
下面是一段浏览器的javascript代码

var url = 'http://api.alice.com/cors';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.send();

浏览器发现这是一个跨域非简单请求,自动发起一个预请求,要求服务器确认允许这样的请求,以下是这个预请求的请求头

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...

预请求中Origin来表示次请求源,Access-Control-Request-Method该字段是必须的,用来列出使用的方法,Access-Control-Request-Headers: 该字段来指定浏览器cors跨域请求会使用的额外头信息

预检请求回应
收到预检请求且确认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 表示可以接受http://api.bob.com的跨源请求,此字段也可以为“*”表示可接受任意网站的跨源请求。
Access-Control-Allow-Methods逗号分隔, 返回服务器可支持的所有跨域请求方法。
Access-Control-Allow-Headers返回服务器所支持跨域访问的所有头信息字段,不限于请求的头信息字段

若浏览器否定了预请求,则返回一个正常的HTTP 响应,其中没有任何CORS相关的头信息字段。这是浏览器会认定服务器不允许此跨域请求,出发一个错误,被XMLHttpRequest的onerror回调函数捕获,控制台打印相应信息:

XMLHttpRequest cannot load http://api.alice.com.
Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.

一次预检请求后
一旦服务器通过了”预见请求” 之后每次浏览器正常的CORS请求,都被当成简单请求,即浏览器请求字段中包含Origin字段,服务器回应也包含一个Access-Control-Allow-Origin字段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值