部署Angular 15至Nginx(Docker)遇MIME类型错误求助
问题描述
将Angular应用通过Docker与Nginx部署至域名下/domain/ui/路径后,出现以下错误:
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec
DEV环境部署后的index.html内容:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>ISA</title> <base href="/ui/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <!-- <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> --> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"></script> <link rel="stylesheet" href="styles.css"></head> <body> <app-root></app-root> <noscript>Please enable JavaScript to continue using this application.</noscript> <script src="runtime.js" type="module"></script><script src="polyfills.js" type="module"></script><script src="vendor.js" type="module"></script><script src="main.js" type="module"></script></body> </html>
已尝试但无效的方案:
- 将
tsconfig.json的target设置为es2015 - 将
dist/ui改为仅dist - 在
nginx.conf中添加错误的MIME类型配置:types { module js; } include /etc/nginx/mime.types;
当前使用的Dockerfile和nginx.conf:
Dockerfile
FROM artifactorycloud.ual.com/v-docker/node:16 AS builder WORKDIR /app COPY package*.json ./ RUN npm install --max-old-space-size=4096 COPY . . RUN npm run build -- --base-href /ui/ --configuration=development FROM artifactorycloud.ual.com/v-docker/nginx:alpine COPY --from=builder /app/dist/ /usr/share/nginx/html # Copy the nginx conf that we created to the container COPY ./nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"]
nginx.conf
server { listen 0.0.0.0:8080; listen [::]:8080; default_type application/octet-stream; gzip on; gzip_comp_level 6; gzip_vary on; gzip_min_length 1000; gzip_proxied any; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_buffers 16 8k; client_max_body_size 256M; root /usr/share/nginx/html; location /ui/health/ { rewrite ^/ui/health/(.*)$ /$1 break; try_files $uri $uri/ /ui/health/index.html; } location /ui/ { rewrite ^/ui/(.*)$ /$1 break; try_files $uri $uri/ /ui/index.html; } }
解决方案
1. 修正Nginx MIME类型配置
删除之前添加的错误types { module js; }配置,确保include /etc/nginx/mime.types;放在default_type之前,让Nginx加载正确的JS MIME类型(application/javascript):
include /etc/nginx/mime.types; default_type application/octet-stream;
2. 修复Nginx路径匹配规则
移除location /ui/和location /ui/health/块中的错误rewrite规则,避免静态文件请求路径被错误改写,导致返回index.html:
location /ui/health/ { try_files $uri $uri/ /ui/health/index.html; } location /ui/ { try_files $uri $uri/ /ui/index.html; }
3. 确保Docker文件复制路径正确
Angular构建产物默认输出到dist/<项目名称>目录,调整Dockerfile的COPY命令,将正确的构建目录复制到Nginx的html/ui路径下:
# 假设构建后产物在dist/ui目录,复制到Nginx的html/ui COPY --from=builder /app/dist/ui/ /usr/share/nginx/html/ui/
4. 验证修复
部署完成后,直接访问/ui/runtime.js,若能看到JS文件内容而非index.html,说明路径匹配正确,MIME类型错误会自动消失。
内容的提问来源于stack exchange,提问作者Kapil Soni

