koa-cors源码解析

介绍

CORS middleware for Koa

Inspired by the great node-cors module.

意为针对 Koa 的 CORS 中间件。它基于 node-cors 模块。

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var koa = require("koa");
var route = require("koa-route");
var cors = require("koa-cors");
var app = koa();

app.use(cors());

app.use(
route.get("/", function () {
this.body = { msg: "Hello World!" };
})
);

app.listen(3000);

源码 koa-cors 0.0.16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
module.exports = function getMiddleware(options) {
// 复制默认参数
options = options || {};

// 声明默认设置的参数
var defaults = {
origin: true,
methods: "GET,HEAD,PUT,POST,DELETE",
};

// 设置非options中的默认参数
for (var key in defaults) {
if (!options.hasOwnProperty(key)) {
options[key] = defaults[key];
}
}

// 设置可暴露的请求头
if (Array.isArray(options.expose)) {
options.expose = options.expose.join(",");
}

// 设置时间期限
if (typeof options.maxAge === "number") {
options.maxAge = options.maxAge.toString();
} else {
options.maxAge = null;
}

// 设置允许的请求方法
if (Array.isArray(options.methods)) {
options.methods = options.methods.join(",");
}

// 设置响应头
if (Array.isArray(options.headers)) {
options.headers = options.headers.join(",");
}

// 返回这个中间件,koa1.x的写法
return function* cors(next) {
var origin;

// 一系列判断逻辑,需要保证origin有值
if (typeof options.origin === "string") {
origin = options.origin;
} else if (options.origin === true) {
origin = this.get("origin") || "*";
} else if (options.origin === false) {
origin = options.origin;
} else if (typeof options.origin === "function") {
origin = options.origin(this.request);
}

// 判断如果为false则跳出中间件
if (origin === false) {
yield next;
return;
}

// 分别将值设置到对应的响应头上
this.set("Access-Control-Allow-Origin", origin);

if (options.expose) {
this.set("Access-Control-Expose-Headers", options.expose);
}

if (options.maxAge) {
this.set("Access-Control-Max-Age", options.maxAge);
}

if (options.credentials === true) {
this.set("Access-Control-Allow-Credentials", "true");
}

this.set("Access-Control-Allow-Methods", options.methods);

var headers;

if (options.headers) {
headers = options.headers;
} else {
headers = this.get("access-control-request-headers");
}

if (headers) {
this.set("Access-Control-Allow-Headers", headers);
}

// 如果是options的预检请求,直接返回204
if (this.method === "OPTIONS") {
this.status = 204;
} else {
yield next;
}
};
};

CORS 字段

Access-Control-Allow-Origin - 指定了允许访问该资源的外域 URI

Access-Control-Expose-Headers - 服务器设置允许浏览器访问特定的头

Access-Control-Max-Age - 指定预请求的结果能够被缓存多久

Access-Control-Allow-Credentials - 当浏览器的 credentials 设置为 true 时是否允许浏览器读取 response 的内容

Access-Control-Allow-Methods - 预检请求的响应,指明实际请求所允许使用的 HTTP 方法

Access-Control-Allow-Headers - 预检请求的响应,指明实际请求中允许携带的首部字段

可以看到这个库主要就是将对应参数设置到 CORS 的响应头字段上,从而达到跨域的目的。

参考链接

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

给阿姨来一杯卡普基诺~

支付宝
微信