用 Vite + React + Ky 联调后端:一个完整表单异常处理指南

🚀 用 Vite + React + Ky 联调后端:一个完整表单异常处理指南

场景

前端使用 Vite 构建,通过 Ky 发送请求:后端后端跑在 172.**.*.**:*****/serve

需求:

  1. 把用户填写的邮箱、姓名保存到后端;
  2. 网络异常业务异常超时 都要优雅提示;
  3. 代码结构清晰,方便日后复用。

1. 项目骨架速览

文件 职责
vite.config.ts 代理 /apihttp://172.**.*.**:*****/serve
src/api/index.ts Ky 封装通用 request 实例
WaitlistForm.tsx React 表单组件,负责校验 + 提交 + 异常处理

2. Vite 代理配置

ts 复制代码
// vite.config.ts
server: {
  proxy: {
    "/api": {
      target: "http://172.**.*.**:*****/serve",
      changeOrigin: true,
      rewrite: path => path.replace(/^\/api/, ""),
    },
  },
}
  • 本地 fetch('后端接口路径') 会被 Vite 转发到真实后端,无 CORS 烦恼。
  • 上线时把 /api 指向真正的域名即可,零改动

3. 用 Ky 封装请求

ts 复制代码
// src/api/index.ts
import ky from 'ky';

const request = ky.create({
  prefixUrl: '/api',   // 自动拼接
  timeout: 600_000,    // 10 min,可按需调整
});

export async function form(data: any) {
  return request.post('后端接口路径', data);
}
  • prefixUrl 让后续路径保持简洁。
  • Ky 自带 timeout / retry / 错误处理 中间件,比原生 fetch 更顺手。

4. React 表单核心逻辑

4.1 状态设计

ts 复制代码
const [formData, setFormData] = useState({
  email: "",
  firstName: "",
  lastName: "",
});
const [submitted, setSubmitted] = useState(false);
const [error, setError] = useState("");

4.2 前端校验

  • 必填字段、邮箱格式、长度 ≤ 50 字符。
  • 早失败:前端先挡一波,减少无效请求。
ts 复制代码
if (!isValidEmail(formData.email)) {
  setError("Please enter a valid email address.");
  return;
}

4.3 提交 & 异常处理

ts 复制代码
try {
  // 1️⃣ 发送
  const response = await form({
    json: {
      email: formData.email,
      firstName: formData.firstName,
      lastName: formData.lastName,
    },
  });

  // 2️⃣ 网络层检查(HTTP 状态码)
  if (!response.ok) {
    throw new Error("Network error. Please check your connection.");
  }

  // 3️⃣ 业务层检查(后端返回 success=false)
  const data: { success?: boolean; msg?: string } = await response.json();
  if (data?.success === false) {
    throw new Error(data.msg || "Submission failed. Please try again later.");
  }

  // 4️⃣ 成功
  setSubmitted(true);
  setFormData({ email: "", firstName: "", lastName: "" });
} catch (error: any) {
  // 5️⃣ 统一收口
  setError(error?.message || "Submission failed. Please try again later.");
}

异常分层

类型 触发示例 最终提示
网络错误 断网、502 "Network error. Please check your connection."
业务错误 {success:false, msg:"邮箱已存在"} "邮箱已存在"
超时 Ky 自带 "Submission failed...(或配置 Ky timeout 提示)
JSON 解析 后端返回 HTML 同上兜底

5. 小技巧 & 踩坑

  1. 后端返回非 JSON

    在 catch 内统一 error.message 兜底即可,用户不会看到晦涩的 Unexpected token <

  2. 代理只在 dev 生效

    打包后把 /api 指向生产域名,或使用环境变量切换。

  3. 调试代理
    vite --debug 或浏览器 Network 面板观察实际转发路径。


6. 总结

  • Vite 代理 解决本地跨域。
  • Ky 比 fetch 更友好,自带 timeout、retry。
  • 异常分层 :HTTP → 业务 → 兜底,全部收敛到 catch,前端提示清晰。
  • 零配置切换:dev 用代理,prod 用真实域名,一行代码都不用改。

把这段逻辑沉淀为 hooks封装函数,以后任何表单都能直接复用。Happy coding!

相关推荐
To_OC7 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic8 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy8 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志8 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble9 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯10 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜11 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司11 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g12 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森12 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http