CORS 详解

CORS:跨域资源共享机制。使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。要想实现CORS跨域,就需要服务器和客户端都做一些配置。

服务端配置

以node服务端为例,使用了express。主要代码如下:

const express = require('express');
const app = express();
app.get('/', function (req, res) {
  res.header('Access-Control-Allow-Origin', 'http://dev.ganji.com:8008');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Expose-Headers', 'Date');
  res.header('Access-Control-Request-Headers', 'X-Custom-Header');
  res.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS,PUT');
  res.json({
    ...
  })
})
var server = app.listen(8081, function () {})
下面对配置项简单介绍:
Access-Control-Allow-Origin

允许跨域访问域名,请求端的域名或者 *,* 表示任意域名都可以访问。

Access-Control-Allow-Credentials

跨域后默认不携带cookie和http的认证信息的,所以就需要添加配置,表示服务器明确许可携带cookie。此时需要注意Origin不能设置为 *, 必须明确指定与请求网页域名一致。
服务端:

res.header('Access-Control-Allow-Credentials', true);

客户端需要在请求中添加withCredentials属性:

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

请求信息
图片描述

Access-Control-Expose-Headers

默认xhr对象的response header中只能拿到六个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,可以在此设置想要拿到的其他字段。

res.header('Access-Control-Expose-Headers', 'Date');
简单请求

简单请求条件:
1、请求方法

  • GET
  • POST
  • HEAD

2、头信息不能超过下边范围

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type 取值范围为:

    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

3、XMLHttpRequestUpload 中没有注册事件监听器

简单请求的客户端和服务端请求过程:
图片描述

复杂请求

如果不满足简单请求的条件,则会发送复杂请求。复杂请求会先用OPTIONS方法发起一个预检请求到服务器,服务器允许后,再发送真实请求。
过程下图:
图片描述
实际请求信息:
第一次的预检请求:
图片描述
第二次实际请求:
图片描述
复杂请求配置介绍:

Access-Control-Request-Method

复杂请求时必须配置,用来指定浏览器的CORS请求会用到哪些HTTP方法,上图中的 PUT。

res.header("Access-Control-Allow-Methods","PUT")
Access-Control-Request-Headers

浏览器CORS请求会额外发送的头信息字段。逗号分隔的字符串。

总结

CORS是服务端和浏览器配合完成的跨域请求,感觉主要是服务端配置好后,浏览器根据服务端的配置的头部和提供的可用的CORS方法来实现跨域。


柚子胖糖
9 声望0 粉丝

引用和评论

0 条评论