Golang模板无法提供WASM服务的解决方法
Golang模板无法提供WASM服务的解决方法 简述: 我有一个使用WebAssembly文件的HTML文件,如果通过Golang服务器作为静态文件加载,一切运行正常。但如果作为模板加载,WebAssembly文件就无法运行,并出现以下错误:
localhost/:1 Uncaught (in promise) CompileError: WebAssembly.compile(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0
详细说明: 我有以下HTML文件:
<!DOCTYPE html>
<html>
<head>
<title>Golang WebAssembly Example</title>
</head>
<body>
<button onclick="handleClick()">Click me</button>
<button onclick="callHandleData()">handleData</button>
<button onclick="notifyme()">notifyme</button>
<div id="result"></div>
<script src="/script/wasm_exec.js"></script>
<script>
const go = new Go();
let wasm;
fetch('main.wasm').then(response =>
response.arrayBuffer()
).then(bytes => WebAssembly.instantiate(bytes, go.importObject)).then(result => {
wasm = result.instance;
go.run(wasm); // This will start the Go runtime
})
function callHandleData() {
let data = handleData(46, "Hello, World!");
// Parse the data using JSON.parse // Parse the data using JSON.parse
let parsedData = JSON.parse(data); // Double stringify for safety
// Access the text property from the parsed object
let text = parsedData.text;
let num = parsedData.number;
alert(data)
alert(text + " What is the "+ num); // Or use text for further manipulation
}
</script>
</body>
</html>
我尝试通过Golang中的模板加载它,如下所示,但遇到了上述错误:
package main
import (
"html/template"
"net/http"
"path/filepath"
)
func handler(w http.ResponseWriter, r *http.Request) {
baseTmpl, err := template.ParseFiles("wasm.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
err = baseTmpl.ExecuteTemplate(w, "wasm.html", nil) // Pass nil as data
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func main() {
http.HandleFunc("/", handler)
// Serve static files
http.HandleFunc("/script/", func(w http.ResponseWriter, r *http.Request) {
filePath := r.URL.Path[len("/script/"):]
if filepath.Ext(filePath) == ".wasm" {
w.Header().Set("Content-Type", "application/wasm")
}
http.ServeFile(w, r, "script/"+filePath)
})
http.ListenAndServe(":8080", nil)
}
更多关于Golang模板无法提供WASM服务的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang模板无法提供WASM服务的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题在于模板引擎会对HTML文件进行转义处理,导致WASM文件的二进制内容被破坏。当作为静态文件服务时,WASM文件保持原始二进制格式;但通过模板加载时,HTML模板引擎会对特殊字符进行转义,破坏了WASM文件的二进制结构。
错误信息中的 3c 21 44 4f 对应ASCII字符 <!DO,这正是HTML文档的开头部分,说明浏览器尝试将HTML文档作为WASM文件解析。
解决方案:
将HTML文件作为静态文件服务,而不是通过模板引擎加载。修改后的代码:
package main
import (
"net/http"
"path/filepath"
)
func main() {
// 直接提供静态HTML文件
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
http.ServeFile(w, r, "wasm.html")
return
}
http.NotFound(w, r)
})
// 提供静态文件服务(包括WASM文件)
http.HandleFunc("/script/", func(w http.ResponseWriter, r *http.Request) {
filePath := r.URL.Path[len("/script/"):]
if filepath.Ext(filePath) == ".wasm" {
w.Header().Set("Content-Type", "application/wasm")
}
http.ServeFile(w, r, "script/"+filePath)
})
http.ListenAndServe(":8080", nil)
}
如果需要使用模板功能(例如动态注入数据),可以采用以下方法:
package main
import (
"html/template"
"net/http"
"path/filepath"
)
func handler(w http.ResponseWriter, r *http.Request) {
// 解析模板但不执行转义
tmpl, err := template.New("wasm.html").ParseFiles("wasm.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 执行模板
err = tmpl.Execute(w, nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func main() {
http.HandleFunc("/", handler)
// 提供WASM文件的静态服务
http.HandleFunc("/script/", func(w http.ResponseWriter, r *http.Request) {
filePath := r.URL.Path[len("/script/"):]
if filepath.Ext(filePath) == ".wasm" {
w.Header().Set("Content-Type", "application/wasm")
}
http.ServeFile(w, r, "script/"+filePath)
})
http.ListenAndServe(":8080", nil)
}
关键点:
- WASM文件必须是原始的二进制格式,不能经过任何转义或编码处理
- 确保WASM文件的Content-Type正确设置为
application/wasm - 如果HTML文件不需要动态内容,直接作为静态文件服务是最简单可靠的方式
- 如果必须使用模板,确保模板引擎不会对WASM文件的引用路径进行修改或转义

