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

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"
}

问题根源及解决办法

  1. no-cors模式的限制
    浏览器使用mode: 'no-cors'发起跨域请求时,会强制将响应标记为不透明(opaque),即使服务器返回了合法JSON,前端也无法读取或解析响应内容。旧版本SvelteKit可能存在特殊兼容处理,新版本则严格遵循浏览器CORS规则。

  2. 中转方式有效的原因
    +server.ts是在服务器端发起请求,不受浏览器CORS规则限制,因此能正常获取并解析Golang服务器的响应,再返回给前端。

  3. 具体修复方案

方案一:移除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:31:03