目录
省流版:你的请求头里混入了脏东西(bushi)!!!
🐶 写在前面,本解决方法是否成功取决于以下条件:
- 使用的是 vue-admin-template 框架(可选)
- 报错详情是 Request header field ... is not allowed(必选)
省略号代指 field 的名称,每个人看到的报错内容可能各有不同,请具体情况具体分析。
网页终端完整报错如下,BBB 和 AAA 分别代指服务器地址和前端地址:
Access to XMLHttpRequest at 'BBB' from origin 'AAA'
has been blocked by CORS policy:
Request header field ... is not allowed by
Access-Control-Allow-Headers in preflight response.
若只关心解决方法,请直接跳转至第三节!
一、回顾(可跳过)
我在上一篇博客中给出了一种解决跨域的方法:
Vue | 基于 vue-admin-template 项目的跨域问题解决方法
由于上述方法在极个别情况下行不通,因此后文将给出另一种方法。
上述方法的本质是,让 localhost 地址代理服务器地址,从而避免跨域问题的出现。但是如果你把项目部署到 Github Pages 上去,就会得到 405 Method Not Allowed 报错。暂时忘了当时是为什么不允许了,好像是因为 Github 认为你的服务器没有取得合格的证书?
二、后续(可跳过)
另一种方法,只需要在 /utils/request.js 文件中添加一行:
service.interceptors.request.use(
(config) => {
// 添加一行
config.url = "AAA" + config.url;
);
AAA 部分替换为你自己的服务器地址。
三、解决跨域问题
3.1 问题翻译
我所遇到的报错如下(地址已盲):
Access to XMLHttpRequest at 'BBB' from origin 'AAA'
has been blocked by CORS policy:
Request header field x-token is not allowed by
Access-Control-Allow-Headers in preflight response.
翻译成中文:从源地址 “AAA” 到目的地址 “BBB” 的 XMLHttpRequest 已被 CORS 策略阻止:在预先检验响应的过程中出错,请求头中不允许有 x-token 字段。
换句话说,我的请求头中有一个名为 x-token 的字段,而它是不被允许的。
3.2 问题分析
我们很自然地想到,把 x-token 删了不就行了吗?关键是,我所有 API 的请求参数都是写在请求体里的啊,怎么会跑到请求头里面去?
答案是,这是 vue-admin-template 框架自带的,而不是我们搞出来的。
还是在 /utils/request.js 文件中:
service.interceptors.request.use(
(config) => {
config.url = "AAA" + config.url;
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
// 看这里!看这里!
config.headers["X-Token"] = getToken();
}
return config;
},
);
想不到吧,X-Token 就在我们的眼皮子底下。根据原作者的注释可知,X-Token 是一个自定义的请求头字段,且自定义请求头字段是可以自行增加和删除的。
3.3 问题解决
把 X-Token 所处的那行删除掉或者注释掉即可:
service.interceptors.request.use(
(config) => {
config.url = "AAA" + config.url;
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
// config.headers["X-Token"] = getToken();
}
return config;
},
);
上述跨域问题前前后后折磨了我半个月,我最后才发现它和那些传统的跨域问题毫无关系。这个故事告诉我们,看得懂英语多么重要啊!这个故事告诉我们,只有在对问题进行分析之后才能找到切入点,从而对症下药。