fetch发起GET请求时已设置的自定义请求头未被Node+Express后端接收的问题
自定义请求头未发送至后端的排查与解决步骤
前端代码可直接修复的问题
mode: same-origin语法错误:代码中没有给字符串值same-origin加引号,运行时会被JS识别为未定义的全局变量,导致整个fetch配置解析失败,所有手动设置的请求头配置全部失效。正确写法为mode: 'same-origin'。- 冗余无效配置:fetch API本身不支持
withCredentials属性,这个是XMLHttpRequest对象的专属配置,写在fetch参数里没有任何作用,可以直接删除;你已经配置的credentials: 'include'才是fetch用来控制跨域带凭证的正确配置。 - 请求触发逻辑异常:从后端打印的请求头特征可以判断,你看到的那次未携带自定义头的请求,根本不是你写的fetch代码发起的——请求头里包含
sec-fetch-mode: 'navigate'、upgrade-insecure-requests: '1'这类标识,属于浏览器直接输入地址、点击页面跳转链接发起的页面导航请求,不是AJAX请求。需要检查你的fetch代码是否正确绑定了触发时机,有没有在代码执行到fetch逻辑之前就发生了页面跳转,导致真正发出的导航请求没有携带任何自定义头。 - 取值边界检查:在fetch逻辑前加个断点,确认
localStorage.getItem('accessToken')的返回值不是null,如果token取值为空,拼接出来的Authorization值为Bearer null,部分浏览器会识别到异常的头值,直接丢弃该自定义头。
后端CORS配置的问题修正
Access-Control-Allow-Origin值格式不合法:这个响应头的取值必须是不带任何路径的完整源地址,你当前写的'localhost:3000/testLogin'既缺少http://协议前缀,又拼接了接口路径,完全不符合CORS规范,浏览器会直接判定校验不通过,拦截自定义头的携带。正确格式例如res.set('Access-Control-Allow-Origin', 'http://localhost:3000')。- 缺少预检请求处理:携带
Authorization、X-Test这类非简单请求头的请求属于跨域非简单请求,浏览器会自动先发送一个OPTIONS方法的预检请求校验权限。你当前的中间件没有拦截处理OPTIONS请求并直接返回成功状态,会导致预检失败,浏览器不会真正发出带自定义头的正式请求。可以在中间件里增加判断:如果是OPTIONS请求直接返回204状态码,结束请求流程。
验证流程
- 打开浏览器开发者工具的网络面板,找到对应
/checkLogin的请求,确认请求类型是fetch/XHR,不是document类型的导航请求;同时确认存在对应的预检OPTIONS请求,且返回状态为2xx。 - 临时移除所有自定义请求头发起测试,确认基础请求链路连通后,再逐个加回自定义头,定位具体是哪个配置触发了拦截。
内容的提问来源于stack exchange,提问作者Timm Nicolaizik
相关产品推荐
相关产品推荐

