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

SvelteKit重新部署后访问报Unexpected token '<'错误如何解决

根因说明

Unexpected token '<'是SvelteKit搭配static adapter部署后非常典型的缓存与资源版本不匹配问题,触发逻辑非常明确:

  • SvelteKit每次构建会为带内容哈希的JS、CSS等静态资源生成全新文件名,同时更新入口HTML文件内的资源引用路径
  • 新版本部署后,如果用户本地缓存了旧版的入口HTML,而旧版HTML中引用的带哈希JS资源已经被新部署覆盖删除,浏览器发起旧JS资源请求时,静态托管服务会因为找不到对应文件,默认fallback返回入口HTML的内容(以<!DOCTYPE html>开头,首个有效字符为<)
  • 浏览器预期返回JS脚本,实际拿到HTML内容,解析时碰到首个字符<就会抛出该错误。手动刷新时浏览器会重新拉取最新版入口HTML,拿到正确的新资源引用路径后问题就会消失。
可落地的修复方案

按优先级落地即可彻底解决问题:

  • 配置分层缓存规则

    对所有文件名带构建哈希的静态资源(JS、CSS、字体、图片等),设置响应头Cache-Control: public, max-age=31536000, immutable,这类资源文件名和内容强绑定,内容变更时文件名一定会同步变化,可以放心长期缓存
    对入口index.html以及所有路由对应的无哈希HTML文件,设置响应头Cache-Control: no-cache,要求浏览器每次访问都校验文件版本,禁止长期缓存入口文件

  • 修正静态服务的fallback逻辑
    不要对所有不存在的请求统一返回200状态的入口HTML,针对JS、CSS、图片等静态资源类型的请求,找不到对应文件时直接返回404状态码即可,避免把HTML内容当成脚本返回。以Nginx为例的配置参考:
    location / {
      try_files $uri $uri/ /index.html;
    }
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
      try_files $uri =404;
      expires 1y;
      add_header Cache-Control "public, immutable";
    }
    
  • 调整CI部署的资源清理逻辑
    不要在部署时全量清空静态资源目录后再上传新构建产物,保留历史构建生成的带哈希静态资源即可——这类资源文件名唯一不会冲突,即使部分用户还持有旧版入口HTML,也能正常加载到对应旧版脚本,不会触发资源不存在的fallback
  • 可选:增加前端自动兜底逻辑
    在SvelteKit的app.html中加入全局错误监听,捕获到脚本加载解析错误时自动触发硬刷新,不需要用户手动操作:
    <script>
      window.addEventListener('error', (e) => {
        const isScriptLoadFail = e.target.tagName === 'SCRIPT';
        const isParseError = e.message?.includes('Unexpected token \'<\'');
        if (isScriptLoadFail && isParseError) {
          location.reload(true);
        }
      }, true);
    </script>
    

内容的提问来源于stack exchange,提问作者David Dal Busco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:15:36