SvelteKit新版本直接请求Golang服务器报JSON解析错误,中转正常
直接从SvelteKit页面请求Golang服务器无法解析JSON响应,中转+server.ts则正常的问题
同一台机器上运行SvelteKit和Golang服务器,开启mode: 'no-cors'时,直接从+page.svelte发送POST请求到Golang服务器无法获取JSON响应:
- Firefox报错:
Uncaught (in promise) SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data - Chrome报错:
+page.svelte? [sm]:312 Uncaught (in promise) SyntaxError: Unexpected end of input (at +page.svelte? [sm]:312:33) at +page.svelte? [sm]:312:33
但通过+server.ts中转请求后能正常得到预期响应。之前使用@sveltejs/kit@1.0.0-next.405版本时代码运行正常,升级到最新版本后出现此问题。
直接请求的+page.svelte代码
async function PostGameData() { await fetch('http://localhost:8001/admin/addproduct', { method: 'POST', mode: 'no-cors', headers: new Headers({ 'Content-Type': 'application/json', Accept: 'application/json' }), body: JSON.stringify(data) }) .then((response) => response.json()) .then((d) => { console.log('🚀 ~ file: +page.svelte ~ line 312 ~ .then ~ Response', d); }); }
Golang服务器代码(main.go)
func(H *DatabaseCollections) AdminAddProduct() gin.HandlerFunc { return func(c *gin.Context) { c.Request.Header.Set("Access-Control-Allow-Origin", "*") var req GameData err := c.Bind(&req) if err != nil{ log.Println("Error : ", err) } c.JSON(http.StatusOK, gin.H{"ok" : " accepted bro"}) } }
中转方式的+server.ts代码
export async function POST({ request }) { const data = await request.json(); let resData await fetch('http://localhost:8001/admin/addproduct', { // credentials: 'same-origin', method: 'POST', mode: 'no-cors', headers: new Headers({ 'Content-Type': 'application/json', Accept: 'application/json' }), body: JSON.stringify(data) }) .then((response) => response.json()) .then((d) => { resData=data console.log('🚀 ~ file: +page.svelte ~ line 312 ~ .then ~ REsponse', d); }); return json(resData) }
中转时+page.svelte的请求代码
async function PostGameData() { await fetch('/api/addgame', { method: 'POST', mode: 'no-cors', headers: new Headers({ 'Content-Type': 'application/json', Accept: 'application/json' }), body: JSON.stringify(data) }) .then((response) => response.json()) .then((d) => { console.log('🚀 ~ file: +page.svelte ~ line 312 ~ .then ~ Response', d); }); }
中转后正常响应
{ "ok": " accepted bro" }
问题根源及解决办法
no-cors模式的限制
浏览器使用mode: 'no-cors'发起跨域请求时,会强制将响应标记为不透明(opaque),即使服务器返回了合法JSON,前端也无法读取或解析响应内容。旧版本SvelteKit可能存在特殊兼容处理,新版本则严格遵循浏览器CORS规则。中转方式有效的原因
+server.ts是在服务器端发起请求,不受浏览器CORS规则限制,因此能正常获取并解析Golang服务器的响应,再返回给前端。具体修复方案
方案一:移除no-cors,配置Golang服务器CORS
使用Gin官方CORS中间件替代手动设置头,确保跨域请求合法:
- 安装中间件:
go get github.com/gin-contrib/cors - 配置Gin路由:
import "github.com/gin-contrib/cors" func main() { r := gin.Default() // 开发环境允许所有来源,生产环境可指定具体域名 r.Use(cors.New(cors.Config{ AllowOrigins: []string{"*"}, AllowMethods: []string{"POST", "GET", "OPTIONS"}, AllowHeaders: []string{"Content-Type", "Accept"}, })) r.POST("/admin/addproduct", H.AdminAddProduct()) r.Run(":8001") } - 前端请求移除
mode: 'no-cors':async function PostGameData() { await fetch('http://localhost:8001/admin/addproduct', { method: 'POST', headers: new Headers({ 'Content-Type': 'application/json', Accept: 'application/json' }), body: JSON.stringify(data) }) .then((response) => response.json()) .then((d) => { console.log('🚀 ~ file: +page.svelte ~ line 312 ~ .then ~ Response', d); }); }
方案二:修正中转代码,继续使用代理
保留+server.ts中转,但修复代码中返回数据的错误:
export async function POST({ request }) { const data = await request.json(); let resData await fetch('http://localhost:8001/admin/addproduct', { method: 'POST', headers: new Headers({ 'Content-Type': 'application/json', Accept: 'application/json' }), body: JSON.stringify(data) }) .then((response) => response.json()) .then((d) => { resData = d // 改为返回Golang服务器的响应,而非原始请求数据 console.log('🚀 ~ file: +server.ts ~ .then ~ Response', d); }); return json(resData) }
内容的提问来源于stack exchange,提问作者sk shahriar ahmed raka
相关产品推荐
相关产品推荐

