nodejs使用cors跨域
8763WEB跨域2018-09-28

相关文章:Nginx的反向代理跨域

最近在学习express,遇到了跨域问题….

背景介绍

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)
跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。

预检请求?

我自己在设置跨域的时候碰到的很多报错其实都是因为预检请求

** cors将请求场景分为 简单请求 和 非简单请求 **

简单请求:

  • 使用的方法是GET,HEAD,POST这三种之一
  • Content-Type 的值是text/plain、 multipart/form-data、 application/x-www-form-urlencoded 这三种之一

那么浏览器检测到该请求非简单请求,会先发送一个预检请求到服务器,以获知服务器是否允许该实际请求

服务器会从预检请求拿到的以下3个信息去和服务器的Response的header对比,来决定是否允许该请求

  • Access-Control-Request-Method :实际请求的方法
  • Access-Control-Request-Headers:实际请求所携带的请求header字段
  • origin:实际请求的源站,域名

服务器header使用字段

Access-Control-Allow-Origin

** 必填字段,值:一个域名, *(表示接受任意域名的请求),也可以读取请求headers中的origin字段 **

如果请求的源与该字段不符合服务器会返回一个正常的HTTP回应,状态码可能为200,但不会包含Access-Control-开头的Origin、Credentials、Headers3个字段,浏览器发现,回应的头信息没有包含Access-Control-Allow-Origin字段就会抛出一个错误,会被XMLHttpRequest的onerror回调函数捕获

Access-Control-Request-Method

** 可选字段,表明服务器支持的所有跨域请求的方法 **

如果你用到除了HEAD,GET,POST之外的方法那么这个字段为必填

Access-Control-Allow-Credentials 可选字段

** 该字段若存在便只能为true,表示服务器许可Cookie可以包含在请求中一起发给服务器 **

对于某些浏览器即使服务器为true,有时候也需要前端设置

1
2
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

若为true Access-Control-Allow-Origin字段便不能为*,必须明确指定域名,Cookie遵循同源政策,只有用服务器域名设置的Cookie才会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

Access-Control-Allow-Headers

** 可选字段,设置Response的额外发送的header字段 **

CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma

如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

Access-Control-Max-Age

** 设置预警请求的结果能够被缓存多久,单位为秒 **

express如何使用cors跨域

在express种使用cors跨域是需要使用第三方模块

1
npm install --save cors

在app.js中写入以下设置

1
2
3
4
5
6
7
8
示例代码
app.all("*", function(req, res, next) {
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Origin", req.headers.origin);
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
next();
});

参考文章:

HTTP访问控制(CORS) https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

欢迎留言交流  (´▽`ʃ♡ƪ)