JS 请求返回 text/html,先查 Nginx 实际送回了哪个文件
JS 地址收到首页 HTML,先沿多层代理查真实 URI 和文件,再区分静态资源失败与 SPA 页面回退,保留正确 MIME 和 API 路由。
浏览器请求一个 .js 地址,收到 text/html,随后报脚本 MIME 类型错误。先打开这次响应的正文:如果里面是首页的 HTML,修改 mime.types 不会把它变成 JavaScript。
在多层 Nginx 代理的静态应用中,资源 URI 可能经过前缀处理后,在最后一层找不到文件,再被 try_files 回退到 index.html。原来的 JS 地址仍显示在浏览器里,但实际返回的文件已经变了。
沿失败资源追踪 URI 和文件
保留浏览器真正请求的 URL、状态码、Content-Type、响应正文和各层对应日志。比较正文中的首页标记,确认它是否确实是入口 HTML;不能只凭头部就认定走了 fallback。
例如外部地址包含 /demo/app1/,静态容器中的文件却位于根目录的 /assets/。要核对每一层实际转发的路径,而不是直接推断最后一层已经去掉前缀。
proxy_pass 是否带 URI、是否使用变量,以及它所在 location 和 rewrite 的条件,都会影响转发路径。按实际加载的配置计算这一请求最终到达哪里,别把一种简单前缀替换写法套进已有正则和变量代理中。
到提供文件的那一层,再核对真实构建产物和有效的 root、alias。root 将 URI 追加到目录路径;alias 替换匹配部分,正则场景还需要正确的捕获条件。外部 URL 看起来正确,不证明拼出来的文件路径存在。
如果产物没有上传完整,先补齐对应版本;如果 URI 被保留或删错,先修路径映射。不能先用 MIME 头盖住缺文件的问题。
首页回退可以保留,静态资源要能明确失败
try_files $uri $uri/ /index.html 会检查候选,未命中后内部跳转到 /index.html。首页真实存在时,它可以成功返回 HTML,因此原 JS 请求也可能得到 200;这与回退目标自身不存在、循环跳转后报 500 是不同情况。
单页应用的页面深链可能需要回退首页,已知静态资源通常应返回文件或明确的不存在。下面只展示在已有 server 内组织这两条路径的示例:实际产物必须确实以 /assets/ 为资源前缀,并已正确处理代理层 URI。
root /srv/www/example;
location /assets/ {
try_files $uri =404;
}
location / {
try_files $uri $uri/ /index.html;
}
/srv/www/example 是示例构建目录,应替换。保留现有 MIME 映射、API 路由、访问限制和必要头部,并检查其他正则 location 的优先级;不能整段覆盖复杂站点,假定这些规则已经随示例存在。
资源目录不存在时返回 404,会让缺失问题更清楚,但不会恢复缺失的 JS。若有全局 error_page 又把 404 改成首页或 200,也要检查最终响应,不能只看这个 location 的文字。
正文已是 JS 时,再处理类型映射
响应确实包含目标 JavaScript、文件路径也正确,却仍给出错误类型时,再核对实际生效的 types、default_type、include 文件,以及上游和代理对头部的处理。已返回首页的请求,强制设置 application/javascript 只会让浏览器尝试把 HTML 当脚本解析。
如果错误转为 rewrite or internal redirection cycle,应另外查 try_files 的终止目标与回退循环,不要把成功返回首页的情况与循环混在一起。
修改前保存各层有效配置和构建目录信息,在受控环境校验后按原服务管理流程加载。分别检查已有 JS、确定不存在的 JS、页面深链、API 和普通首页:已有资源返回正确内容及类型,缺失资源保留预期状态,应用导航仍正常。回退时恢复路径与 location 修改,不删除整个站点的回退规则,也不通过修改全部响应类型掩盖仍在返回的首页。


