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

Django部署SvelteKit构建产物时出现大量MIME类型不匹配错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 23:18:33