了解跨域之前我们需要知道什么叫”同源策略“,即域名,协议,端口相同。
我们都知道之前有很多跨域方式:
- JSOP,动态创建<script>,设置src获取跨域资源。只能GET请求。
- 空iframe加form。可支持POST请求。
- window.name + iframe跨域。
- postMessage + iframe跨域。
接下来主角登场,今天我们说的是CORS(跨域资源共享)
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)
- 只要同时满足以下两大条件,就属于简单请求。
- 请求方法是以下三种方法之一:
HEAD
GET
POST- HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
- 凡是不同时满足上面两个条件,就属于非简单请求。
简单请求
实现过程
(1)后端主要设置Access-Control-Allow-Origin是允许跨域的域名,如果设置*,则表示接受任意域名的请求。
如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。
(2)前端不需要做什么。
非简单请求
非简单请求是请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight);
这种情况下除了设置origin,还需要设置Access-Control-Request-Method以及Access-Control-Request-Headers
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age 该字段可选,用来指定本次预检请求的有效期,单位为秒。
- 后端
const query = ctx.request.query
// 如果需要http请求中带上cookie,需要前后端都设置credentials,且后端设置指定的origin
ctx.set('Access-Control-Allow-Origin', 'http://localhost:9099')
ctx.set('Access-Control-Allow-Credentials', true)以及Access-Control-Request-Headers
ctx.set('Access-Control-Request-Method', 'PUT,POST,GET,DELETE,OPTIONS')
ctx.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, t')
- 前端
接口请求设置headers属性
如headers: {'X-Custom-Header': 'value'};
xhr.setRequestHeader('X-Custom-Header', 'value');
CORS优势在于支持所有类型的HTTP请求,也可支持全部跨域资源。
网友评论