Django部署SvelteKit构建产物时出现大量MIME类型不匹配错误
问题背景
部署SvelteKit构建产物到Django时,浏览器提示大量资源因MIME类型(text/html)不匹配被拦截。手动修改index.html中所有资源URL前缀为/static/后可正常访问,但需要自动化的修复方法或更优部署方案。
相关配置
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="icon" href="/static/icons/tabIcon.svg" /> <link rel="stylesheet" href="/static/posty.css" /> <meta http-equiv="content-security-policy" content="" /> <link rel="modulepreload" href="/static/_app/immutable/start-6f351e07.js" /> <link rel="modulepreload" href="/static/_app/immutable/chunks/index-d9a79891.js" /> <link rel="modulepreload" href="/static/_app/immutable/chunks/index-d827f58a.js" /> <link rel="modulepreload" href="/static/_app/immutable/chunks/singletons-eca981c1.js" /> </head> <body> <div> <script type="module" data-sveltekit-hydrate="45h" crossorigin> import { set_public_env, start, } from "/static/_app/immutable/start-6f351e07.js"; set_public_env({}); start({ target: document.querySelector('[data-sveltekit-hydrate="45h"]') .parentNode, paths: { base: "", assets: "/static/" }, session: {}, route: true, spa: true, trailing_slash: "never", hydrate: null, }); </script> </div> </body> </html>
svelte.config.js
import adapter from '@sveltejs/adapter-static'; import preprocess from 'svelte-preprocess'; /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: preprocess(), kit: { adapter: adapter({ assets: 'build/assets', out: 'dist', fallback: 'index.html', precompress: false }) } }; export default config;
settings.py
# ... DEBUG = True STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'build/assets') ] STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'build')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] # ...
错误信息
The resource from “http://127.0.0.1:8000/_app/immutable/pages/__layout.svelte-bd484656.js” was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff).
The resource from “http://127.0.0.1:8000/_app/immutable/assets/__layout-ce6f71c3.css” was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff).
The resource from “http://127.0.0.1:8000/_app/immutable/chunks/index-d9a79891.js” was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff).
... 9+ more errors
即使使用python manage.py runserver --nostatic --insecure借助Whitenoise也无法解决问题。
解决方案
1. 让SvelteKit自动生成带/static/前缀的资源路径
修改svelte.config.js,在kit配置中添加paths.assets指定资源基础路径,构建时所有资源URL会自动带上/static/前缀,无需手动修改index.html:
import adapter from '@sveltejs/adapter-static'; import preprocess from 'svelte-preprocess'; /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: preprocess(), kit: { paths: { assets: '/static' // 指定资源的基础URL前缀 }, adapter: adapter({ assets: 'build/assets', out: 'dist', fallback: 'index.html', precompress: false }) } }; export default config;
重新构建SvelteKit项目,生成的index.html中所有资源路径会自动包含/static/前缀。
2. 调整Django静态文件配置匹配构建产物路径
当前STATICFILES_DIRS指向build/assets,但SvelteKit构建的_app目录在dist下(adapter的out设为dist),需确保Django能正确找到所有静态资源:
- 修改SvelteKit的adapter配置,统一资源输出路径:
adapter: adapter({ assets: 'static', // 直接输出到Django识别的静态目录 out: 'build', // 输出到Django模板目录对应的build文件夹 fallback: 'index.html', precompress: false })
- 同步调整Django的
STATICFILES_DIRS:
STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static') ]
构建后SvelteKit的资源直接输出到Django能识别的静态目录,无需额外移动文件。
3. 部署流程自动化
若保留现有目录结构,可在构建脚本中添加自动替换index.html路径的步骤:
- Linux/macOS构建脚本示例:
# 构建SvelteKit npm run build # 替换index.html中所有/_app开头的路径为/static/_app sed -i 's/href="\/_app/href="\/static\/_app/g' build/index.html sed -i 's/src="\/_app/src="\/static\/_app/g' build/index.html
- 或在package.json的scripts中添加:
"scripts": { "build": "vite build && sed -i 's/href=\"\\/_app/href=\"\\/static\\/_app/g' build/index.html && sed -i 's/src=\"\\/_app/src=\"\\/static\\/_app/g' build/index.html" }
每次构建后自动完成路径替换,无需手动操作。
4. 更优部署方案:分离前后端服务
若项目复杂度较高,建议将SvelteKit作为独立前端服务部署(如用Nginx托管静态文件),Django作为后端API服务,通过跨域请求交互:
- SvelteKit构建后,用Nginx托管静态文件,配置反向代理到Django API;
- 在SvelteKit中配置API_BASE_URL环境变量,指向Django的API地址;
- Django配置CORS允许前端域名访问,确保跨域请求正常。
内容的提问来源于stack exchange,提问作者Lun

