使用koa开发想要开启 cors 非常简单,已经有对应的库:@koa/cors。
基本用法
const cors = require('@koa/cors')
app.use(cors());
只需要两行,接口就会在返回数据的时候带上Access-Control-Allow-Origin
响应头。默认允许所有请求方式跨域即Access-Control-Allow-Origin
默认为*
。
携带cookies
为了安全考虑,携带cookies的跨域请求只允许Access-Control-Allow-Origin
为单一域名,即只支持一个域名在请求的时候携带cookies。且需要带上响应头Access-Control-Allow-Credentials
对 @koa/cors
添加配置 origin 和 credentials:
const cors = require('@koa/cors')
app.use(cors({
origin: 'http://koa.com', // 前端地址
credentials: true
}));
同时,前端要发起携带cookies的跨域请求,需要设置withCredentials
为true
,如果你是使用axios,只需要在请求配置里加上一句withCredentials: true
,请看例子:
export const upload = (requestParams) => {
return axios({
method: 'post',
url: 'http://localhost:8000/api/admin/upload',
data: requestParams,
withCredentials: true
})
}
这样前端(http://koa.com
)就可以向后端(http://localhost:8000
)发送请求了。
多域携带cookies发送请求
如果你的前端地址只有一个,给@koa/cors
的origin添加一个域名就能满足需求,如果需要支持跨域的域名有多个呢?
通过观察@koa/cors
的 单元测试用例,可以发现origin是支持用函数的方式传入的。这样我们就可以维护一个域名数组,判断请求地址是否在域名数组内,就能知道是否要对请求地址提供携带cookies请求支持了。
要想知道发起请求的前端地址,可以使用ctx.request.header.origin
。
// 允许的域名数组
arr_ym = ['http://www.baidu.com','https://www.sina.com.cn/','https://spec.csdn.net/']
app.use(cors({
origin(ctx) {
if (arr_ym.includes(ctx.request.header.origin)) {
// 响应代码
}
},
credentials: true
}));
注意ctx.request.header.origin
和ctx.request.origin
是不同的。ctx.request.origin
是接口域名,ctx.request.header.origin
是发起请求的页面域名。