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

Golang文件服务器子路径下HTML无法加载.wasm文件问题

问题:Golang子路径文件服务器无法加载.wasm资源

我用Golang搭建带子路径的文件服务器,现有代码如下:

func main() {
    fs := http.FileServer(http.Dir("../../dist/"))
    
    http.Handle("/", fs)
    http.Handle("/a/", http.StripPrefix("/a/", fs))

    http.ListenAndServe(":8081", nil)
}

../../dist/目录下包含index.html和多个.wasm文件。访问:8081/时文件服务器运行正常,但访问:8081/a/时,index.html可正常加载,但其引用的.wasm文件加载失败。HTML代码如下:

<html>
<head>
    <link rel="preload" href="/start-4f9b00c561355aee_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
    <link rel="modulepreload" href="/start-4f9b00c561355aee.js">
</head>
<body>
    <script type="module">
    import init from '/start-4f9b00c561355aee.js';
    init('/start-4f9b00c561355aee_bg.wasm');
    </script>
</body>
</html>

我已尝试添加http.StripPrefix(如上代码所示),甚至设置Header().Set("content-type", "application/wasm"),但都无法让/a/路径正常加载.wasm文件。请问我遗漏了什么?


核心问题分析

你遇到的问题根源在HTML资源的引用路径:所有.wasm、.js资源都是以/开头的绝对路径。当浏览器访问/a/时,会直接请求/start-xxx.wasm(根路径下的资源),而不是/a/start-xxx.wasm。虽然你的Go代码把/a/映射到了dist目录,但浏览器根本没往/a/路径发送资源请求,自然找不到文件。

解决方案

方案1:修改HTML为相对路径引用

把所有绝对路径的资源引用改成相对路径(去掉开头的/),让浏览器自动根据当前URL拼接路径:

<html>
<head>
    <link rel="preload" href="start-4f9b00c561355aee_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
    <link rel="modulepreload" href="start-4f9b00c561355aee.js">
</head>
<body>
    <script type="module">
    import init from './start-4f9b00c561355aee.js';
    init('./start-4f9b00c561355aee_bg.wasm');
    </script>
</body>
</html>

这样访问/a/时,浏览器会请求/a/start-xxx.wasm,Go的StripPrefix("/a/", fs)会去掉前缀/a/,正确映射到dist目录下的对应文件。

方案2:通过前端构建工具设置基础路径(适合有构建流程的项目)

如果你的前端是用Vite、Webpack等工具构建的,可以直接配置base选项为/a/,构建后所有资源路径会自动带上/a/前缀:

  • 比如Vite的vite.config.js:
export default {
  base: '/a/'
}

构建后的HTML资源引用会变成/a/start-xxx.wasm,这样不管访问/还是/a/,资源请求路径都能被Go的路由正确处理:

  • 访问/时,请求/a/start-xxx.wasm会被http.Handle("/a/", ...)路由处理;
  • 访问/a/时,请求/a/start-xxx.wasm同样会被该路由处理。

方案3:自定义Go Handler统一处理路径(不修改HTML的可选方案)

如果不想改动前端代码,可以自定义一个Handler,判断请求路径是否属于子路径,再转发到对应的文件服务器:

func main() {
    distFS := http.FileServer(http.Dir("../../dist/"))

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // 检查请求是否来自/a/路径
        if strings.HasPrefix(r.URL.Path, "/a/") {
            http.StripPrefix("/a/", distFS).ServeHTTP(w, r)
            return
        }
        // 其他请求直接用根路径的文件服务器
        distFS.ServeHTTP(w, r)
    })

    http.ListenAndServe(":8081", nil)
}

不过这个方案治标不治本,因为浏览器请求的还是根路径资源,只是通过Go Handler强制转发,不如前两种方案优雅。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:47:06