You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vite+React部署在反向代理后获取图片时出现MIME类型错误

Vite+React反向代理MIME类型错误问题排查与修复

问题描述

  • 直接通过Docker Compose开放的端口访问Vite+React应用(如http://localhost:1234/react/home.html)时,应用正常运行;
  • 通过NGINX反向代理路由(http://localhost/react/index.html)访问时,出现MIME类型错误:
Failed to load module script: 
Expected a JavaScript module script but the server responded with a MIME type of "image/png". 
  • 对比请求头:成功请求的Sec-Fetch-Dest为image,失败请求为script,Referer字段存在差异;移除图片后应用其余功能正常,CSS中的背景图片可正常加载;
  • 测试Vite+React演示项目时出现相同错误,排除图片导入方式问题。

相关配置

NGINX配置片段(已引入/etc/nginx/mime.types)

# React dev environment
# Regex to capture the rest of the path. It seems that with the variable in the proxy-pass, the standard rules don't apply.
location ~ ^/react/(.*)$ {
    # Resolver hack so NGINX config won't fail at startup when React is precompiled.
    # We need this since we can run local setup without react
    resolver 127.0.0.11 valid=60s;
    set $upstream_react boninabox-react;
    proxy_pass http://$upstream_react:1234/react/$1;

    # Enable hot reloading for dev server
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    add_header Access-Control-Allow-Origin *;
    # --- end hot reloading
}

Vite配置(vite.config.js)

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'

export default defineConfig({
  plugins: [react()],
  base: "/react/",
  server: {
    host: true,
    port: 1234
  },
  build: {
    manifest: true,
    rollupOptions: {
      input: ['/src/home.jsx', '/src/project.jsx'],
    },
  },
})

问题原因

核心矛盾在于NGINX代理路径与Vite的base配置冲突,加上变量式proxy_pass的特殊解析规则:

  1. Vite的base设置为/react/,意味着所有资源请求都会以/react/作为前缀;
  2. NGINX的正则^/react/(.*)$捕获路径后,在proxy_pass中又添加了/react/前缀,导致代理后的URL出现重复的/react/(如http://boninabox-react:1234/react/index.html);
  3. 当使用变量($upstream_react)在proxy_pass中时,NGINX不会自动调整URL路径的匹配逻辑,导致资源请求的路由解析混乱——原本应该请求图片的路径被错误映射到脚本资源,反之亦然,最终触发MIME类型不匹配错误。

修复方案

方案1:修正NGINX代理路径(推荐)

调整proxy_pass的路径,去掉重复的/react/前缀,让Vite的base配置负责处理资源路径前缀:

location ~ ^/react/(.*)$ {
    resolver 127.0.0.11 valid=60s;
    set $upstream_react boninabox-react;
    // 移除proxy_pass中的/react/,直接转发捕获的$1部分
    proxy_pass http://$upstream_react:1234/$1;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    add_header Access-Control-Allow-Origin *;
}

修改后,请求/react/index.html会被代理到http://boninabox-react:1234/index.html,Vite的base: "/react/"会自动为所有资源请求添加/react/前缀,确保路径解析正确。

方案2:调整Vite的base配置(备选)

若不想修改NGINX配置,可将Vite的base设置为空字符串,使用相对路径加载资源:

export default defineConfig({
  // ...其他配置
  base: "",
  // ...
})

注意:此方案可能影响生产构建时的资源路径,需结合生产环境部署路径调整,灵活性不如方案1。

验证步骤

修改配置后,重启NGINX和Vite服务,访问http://localhost/react/index.html,检查请求头的Sec-Fetch-Dest是否与资源类型匹配,确认MIME类型错误是否消失。

内容的提问来源于stack exchange,提问作者JM Lord

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 12:17:09