同源策略(Same-origin policy)
如果两个URL的协议、域名、端口号都相同,则表示他们符合同源策略。
跨源资源共享 ( Cross-Origin Resource Sharing )
当 Web 资源请求由不同源的资源时,会发起跨源 HTTP 请求(cross-origin HTTP request)。
script,img,iframe,link等标签都可以跨源加载资源,而不受同源策略的限制。默认情况下,XHR对象处于某种安全策略不能访问跨源资源。
如果XHR要访问跨源资源,就必须使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是否成功。
一般来说,跨源请求可以大致分为两种,简单的跨源请求和非简单跨源请求。
简单的跨源请求:
简单的跨源请求必须满足下面的条件:
- 请求的方法是 GET 、 POST 、 HEAD 其中之一。
- HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Content-Type ( 只能是application/x-www-form-urlencoded 、 multipart/form-data 、 text/plain 其中之一)
反之,如果有违背上面规则中的任意一条,那么就不是简单的跨源请求。
非简单的跨源请求:
非简单的跨源请求相对于简单的跨源请求来说区别在于,请求在发出去之前,浏览器会先发送一个 Preflighted (预检) 请求,用来向服务器端确认接下来要进行的请求是否是被允许的。Preflighted 请求使用OPTIONS方法。
** 预检请求请求头部字段:**
- Origin 表示请求来自哪个源。
- Access-Control-Request-Method 该字段是必须的,请求自身使用的方法。
- Access-Control-Request-Headers 自定义头部信息,多个值以逗号分隔。
** 预检请求响应头部字段:**
- Access-Control-Allow-Origin 允许访问该资源的外域 URI
- Access-Control-Allow-Methods 允许的方法。多个值以逗号分隔。
- Access-Control-Request-Headers 允许的头部,多个值以逗号分隔。
- Access-Control-Max-Age 这个Preflighted 请求的缓存时间(秒)。
Preflighted请求结束后,结果将按照响应中指定的时间缓存起来。因此付出的代价是在第一次发送请求时多一次HTTP请求。
支持Preflighted请求的浏览器包括Firefox 3.5,Safari 4,Opera12,Chrome 4 ,IE10以上。(IE10及更早版本都不支持,CORS 机制是借由 XDomainRequest 对象完成的。)
以下是一个非简单的跨源请求示例:
JavaScript:
var url = 'http://api.alice.com/cors';
var xhr = createCORSRequest('PUT', url);
xhr.setRequestHeader(
'X-Custom-Header', 'value');
xhr.send();
** Preflighted请求:**
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...
** Preflighted响应:**
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 1728000
Content-Type: text/html; charset=utf-8
参考:
https://www.html5rocks.com/en/tutorials/cors/
http://www.smartcitychina.cn/QianYanJiShu/2017-02/8220.html
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
《Javascript高级程序设计》