设置script为module后,Express认证静态路由无法加载脚本的问题
问题原因分析
1. ES模块请求的凭证默认行为差异
把<script>标签设为type="module"后,浏览器发起的模块文件请求默认不会携带Cookie(除非显式配置凭证属性)。如果你的静态文件路由认证依赖Cookie存储JWT令牌,模块请求就会因未携带凭证被拦截。
而普通脚本请求会自动携带当前域名下的Cookie,所以之前能通过认证校验。
2. 预加载请求触发的拦截逻辑
浏览器加载ES模块时,会自动发送预加载(preload)请求获取模块文件。部分认证中间件未正确处理这类请求的头信息(比如Accept头为*/*,或包含非标准脚本类型),误将其判定为未授权的API请求,直接返回拦截页面。
3. 请求头特征导致中间件误判
ES模块请求的Sec-Fetch-Dest、Accept头等与普通脚本请求存在差异:
- 普通脚本请求的
Sec-Fetch-Dest值为script - ES模块请求的
Sec-Fetch-Dest值为module
如果你的认证中间件的判断逻辑未覆盖module类型的请求,就会把模块文件请求当成未授权请求拦截。
解决办法
显式配置脚本凭证模式:在module类型的script标签上添加
credentials="include",强制请求携带Cookie:<script type="module" src="/index.js" credentials="include"></script>修改认证中间件兼容模块请求:
- 检查请求的
Sec-Fetch-Dest头,若值为module,按静态文件的认证逻辑处理(比如允许携带Cookie的请求通过) - 单独放行预加载类型的请求,或对预加载请求做针对性校验
- 确保静态文件路由的认证逻辑覆盖普通脚本和模块脚本的请求头特征
- 检查请求的
调整JWT携带方式:如果使用Bearer令牌而非Cookie,需确保模块请求能正确携带
Authorization头。可以通过页面加载时手动fetch模块并注入,或用服务端渲染方式将令牌嵌入模块请求的头信息中。
内容的提问来源于stack exchange,提问作者Rudy
相关产品推荐
相关产品推荐

