共计 1530 个字符,预计需要花费 4 分钟才能阅读完成。
话不多说,一个字,干!
前端配置如下:
axios.defaults.withCredentials = true; // 配置为 true
axios.post(‘http://localhost:3000/tpzdz/vote/all’, {
openid: ‘oJ0mVw4QrfS603gFa_uAFDADH2Uc’,
date: ‘2018-11-21’
}).then(function (response) {
console.log(response)
})
前端配置 withCredentials = true 后端的跨域也需要配置
app.use(async (ctx, next) => {
ctx.set(‘Access-Control-Allow-Origin’, ctx.request.header.origin);
ctx.set(‘Access-Control-Allow-Credentials’, true);
await next();
});
// 防止每次请求都返回 Access-Control-Allow-Methods 以及 Access-Control-Max-Age,
// 这两个响应头其实是没有必要每次都返回的,只是第一次有预检的时候返回就可以了。
app.use(async (ctx, next) => {
if (ctx.method === ‘OPTIONS’) {
ctx.set(‘Access-Control-Allow-Methods’, ‘PUT,DELETE,POST,GET’);
ctx.set(‘Access-Control-Max-Age’, 3600 * 24);
ctx.body = ”;
}
await next();
});
实例展示完了,我们来讲讲都是怎么回事
withCredentials: 默认情况下,跨源请求不提供凭据 (cookie、HTTP 认证及客户端 SSL 证明等)。通过将 withCredentials 属性设置为 true,可以指定某个请求应该发送凭据。默认值为 false。true:在跨域请求时,会携带用户凭证 false:在跨域请求时,不会携带用户凭证;返回的 response 里也会忽略 cookie
当配置了 withCredentials = true 时,必须在后端增加 response 头信息 Access-Control-Allow-Origin,且必须指定域名,而不能指定为 *!!!
那么问题就来了,若是多个域名呢?我配置的是任意域名都可以访问,但是这样并不安全。建议做法是创建一个数组,每次去检测域名是否在数组内,存在则继续
讲到这里了,那么延伸一下 post 请求下的 options
options 它是一种探测性的请求,通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。
前台跨域 post 请求,由于 CORS(cross origin resource share)规范的存在,浏览器会首先发送一次 options 嗅探,同时 header 带上 origin,判断是否有跨域请求权限,服务器响应 access control allow origin 的值,供浏览器与 origin 匹配,如果匹配则正式发送 post 请求。
每一次非简单请求都会实际上发出两次请求,一次预检一次真正请求,这就比较损失性能了。
所以就有了 2 图的中间件。Access-Control-Max-Age: 86400 设置一个相对时间,在该非简单请求在服务器端通过检验的那一刻起,当流逝的时间的毫秒数不足 Access-Control-Max-Age 时,就不需要再进行预检,可以直接发送一次请求。
但是为什么会有两个中间件的设置呢,推荐文章 https://www.jb51.net/article/… 很细致哦