HTML页面调用API被跨域拦截的根源是浏览器同源策略,开发期最稳妥解法是配置代理(如Vite的server.proxy或Vue CLI的devServer.proxy),将/api请求转发至后端地址,使前端请求看似同源;同时避免硬编码后端地址,改用相对路径,并确保API返回标准JSON格式。

HTML 页面无法正确调用 API,不是后端没写完,而是前端在真实环境里连不上接口、拿不到数据、或者拿到数据但格式不对——这几乎全是联调阶段暴露的契约问题,不是代码 bug。
HTML 页面怎么发请求才不被跨域拦截
浏览器默认禁止跨域请求,而前后端分离后,前端静态文件常运行在 http://localhost:5173(Vite)、http://127.0.0.1:8080(Vue CLI),后端 API 在 http://localhost:8081 或 http://api.example.com,域名+端口不同即触发跨域。
- 开发期最稳妥的解法是配代理:Vite 项目改
vite.config.ts的server.proxy,Webpack 项目改vue.config.js的devServer.proxy,把/api前缀请求转发到后端地址,让浏览器以为是同源请求 - 不要在 HTML 里硬编码后端地址,用相对路径或环境变量:比如
fetch('/api/users')比fetch('http://localhost:8081/api/users')更安全,部署时只需配 Nginx 反向代理即可生效 - 后端如果临时开启 CORS(如 Spring Boot 加
@CrossOrigin),只应在开发环境启用,生产环境必须关掉——CORS 是给前端“开绿灯”,不是解决根本问题的手段
API 返回 JSON 格式不一致导致前端解析失败
常见现象是 response.json() 报错 Unexpected token ,本质是后端返回了 HTML(比如 404 页面)或纯文本,而非 JSON。
- 先确认后端是否真返回了
Content-Type: application/json响应头;Spring Boot 默认会设,但若 Controller 方法没加@ResponseBody或没用@RestController,就可能返回视图而不是 JSON - 统一响应结构是避免字段名混乱的关键:约定所有接口都返回类似
{ "code": 200, "data": {}, "message": "" }的格式,前端用固定 key 提取数据,而不是每次写res.data?.userList || res.users - 后端抛异常时,别直接 throw new RuntimeException(),要捕获并包装成标准错误响应,否则前端 fetch 收到 500 状态码但 body 是空白或堆栈日志,没法友好提示用户
Mock 数据和真实 API 切换时出问题
前端用 Mock 先跑通逻辑很合理,但上线前切真实接口时,常因 URL、参数名、字段嵌套层级等细微差异崩掉。
立即学习“前端免费学习笔记(深入)”;
- Mock 工具(如 Mock.js、MSW)必须严格按最终 API 文档模拟,包括路径、query 参数、body 字段名、甚至空数组/空对象的返回值——不能“差不多就行”
- 建议在 HTML 或 JS 中抽一个
API_BASE_URL变量,开发时指向 mock 服务,打包时通过环境变量替换为真实地址,避免手动改一堆fetch调用 - 接口文档必须包含示例请求和响应体,且由后端用 Swagger 或 Apifox 自动生成并实时更新;前端联调前先用 Postman 手动验证一遍,比直接写进页面更早发现问题
真正卡住联调的,往往不是某个函数不会写,而是双方对“这个接口到底长什么样”理解有偏差——一个字段叫 user_id 还是 userId,分页参数用 page 还是 pageNum,空列表返回 [] 还是 null,这些细节必须白纸黑字写进契约,而不是靠口头约定或看代码猜。



















