跨域方法之CORS

简介

CORS 全称:跨域资源共享(Cross-origin resource sharing),主要用来解决因为同源策略致使的 XMLHttpRequest 和 Fetch 没法获取请求资源的问题。html

这里以 XMLHttpRequest 为例,server 端以 express 框架为例前端

分类

浏览器将CORS请求分红两类:简单请求和非简单请求。只要同时知足如下两大条件,就属于简单请求:chrome

1.请求方法是如下三种方法之一:express

  • head
  • get
  • post

2.请求头不超出如下几种字段:跨域

  • accept
  • accept-language
  • content-language
  • content-type:只限于三个值,application/x-www-form-urlencoded、multipart/form-data、text/plain

非简单请求:当不符合上面的条件时,就是非简单请求。浏览器

解决办法

简单请求:只须要在 server 端设置请求头:cookie

res.header('Access-Control-Allow-Origin', '*'); //或者相应的origin
复制代码

非简单请求:app

非简单请求会在正式通讯以前,会增长一次 options 查询请求,称为"预检"请求(preflight)。这时想要实现跨域资源共享,除了 origin 外,还要设置其余属性:cors

let xhr = new XMLHttpRequest(),
    method = 'post',
    url = 'http://127.0.0.1:3000/getData';

xhr.open(method, url, true);
// 自定义头部
xhr.setRequestHeader('X-requestId', '123456');
xhr.send({ form: 'data' });
xhr.onreadystatechange = function () {
  if(xhr.readyState === 4) {
    console.log('success')
  }
}
复制代码

好比我在代码中设置了一个自定义的头部,那么此时就须要在 server 设置:框架

res.header('Access-Control-Allow-Headers', 'X-requestId');
复制代码

除此以外,由于咱们设置跨域通常都是统一设置,所以,能够加上这个:

res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); // 这里包括你项目中各类请求方法
复制代码

cookie的问题

在跨域时,想带上 cookie 须要设置:

// 前端:
xhr.withCredentials = true;

// server端
res.header('Access-Control-Allow-Credentials', true);
复制代码

注意事项:

  • 携带 cookie 时,Access-Control-Allow-Origin 字段必须为前端请求的origin,不能是 “*”
  • 前端没法获取和修改 server 端种到本地的 cookie
  • 在 chrome 浏览器里,cookie 也不会出先在请求头中(不跨域时是有的)
  • 普通请求若是携带 cookies, 也不会触发“预检”请求

XMLHttpRequest

CORS请求时,XMLHttpRequest 对象的 getResponseHeader() 方法只能拿到6个基本字段:

  • Cache-Control、
  • Content-Language、
  • Content-Type、
  • Expires、
  • Last-Modified、
  • Pragma。

若是想拿到其余字段,就必须在服务端 Access-Control-Expose-Headers 里面指定,例如:

res.header('Access-Control-Expose-Headers', 'X-requestId')
复制代码

参考连接:

相关文章
相关标签/搜索