SvelteKit表单调用Golang后端POST API时出现400错误求助
问题分析与修复方案
你的代码存在几个关键问题,导致Golang后端无法正确解析JSON请求体,从而返回400错误:
1. 错误使用mode: "no-cors"
设置mode: "no-cors"后,浏览器会强制将请求的Content-Type改为text/plain,而非你指定的application/json。Golang后端期望接收JSON格式数据,自然会解析失败,抛出类似"invalid character..."的错误。同时no-cors模式下你也无法读取响应内容,完全没必要启用这个模式。
修复:删除mode: "no-cors"配置。
2. 跨域请求头设置错误
Access-Control-Allow-Origin、Access-Control-Allow-Methods是后端(Golang服务)需要返回的响应头,不是前端请求里要添加的。前端请求中加入这些头毫无意义,反而可能干扰请求正常发送。
修复:删除请求头中的这两个跨域相关配置。
3. 参数校验顺序错误
你当前是先发送请求到Golang后端,再检查name和deposit是否为空。正确逻辑应该是先校验参数,不合格直接返回错误,避免发起无效的后端请求。
修复:将参数校验逻辑移到发送请求之前。
4. Deposit类型未转换
formData.get("deposit")获取到的是字符串类型,直接JSON序列化后,若Golang后端期望数字类型的deposit,会导致类型不匹配。需要将其转换为数字类型,同时校验有效性。
修复:用Number(deposit)转换值,并添加非数字/负数校验。
修改后的+page.server.js代码:
// /src/routes/account/+page.server.js import { fail } from '@sveltejs/kit' export const actions = { default: async ({ request, fetch, cookies }) => { const data = await request.formData() const name = data.get("name")?.trim() const depositStr = data.get("deposit")?.trim() // 优先做参数校验 if (!name || !depositStr) { return fail(400, { name, message: "Missing name or deposit" }) } // 转换并校验deposit的有效性 const deposit = Number(depositStr) if (isNaN(deposit) || deposit <= 0) { return fail(400, { name, message: "Deposit must be a positive number" }) } const body = JSON.stringify({ name, deposit }) console.log("body:", body); try { const res = await fetch("http://127.0.0.1:8080/account", { body, method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" } }) if (!res.ok) { // 处理后端返回的错误信息 const errorData = await res.json().catch(() => null) return fail(res.status, { name, message: errorData?.message || "Failed to create account" }) } cookies.set('name', name, { path: '/' }) console.log(`response status: ${res.status}, cookies: ${cookies.get("name")}`); return { message: 'account created' } } catch (err) { console.error("Request failed:", err) return fail(500, { name, message: "Failed to connect to backend" }) } } }
额外注意事项
- 确保你的Golang后端已正确配置CORS,允许来自SvelteKit服务域名(比如默认的
http://localhost:5173)的请求。 - Golang后端要使用正确的JSON解析方式,比如
json.NewDecoder(r.Body).Decode(&yourStruct)来解析请求体。
内容的提问来源于stack exchange,提问作者rejuan kenobi
相关产品推荐
相关产品推荐

