科技知识港
第二套高阶模板 · 更大气的阅读体验

JSON跨域问题处理:前端开发中的常见坑与解法

发布时间:2025-12-14 14:20:57 阅读:270 次

什么是JSON跨域问题

在做网页开发时,经常会遇到这样的情况:本地页面想从另一个域名下获取数据,比如从 api.example.com 拿用户信息,结果浏览器直接报错,控制台红字一片。这就是典型的跨域问题。虽然你请求的数据明明存在,接口也能正常访问,但浏览器出于安全考虑,硬是拦了下来。

这种限制叫做“同源策略”,也就是说,只有协议、域名、端口都一致,才允许读取对方返回的数据。而我们常用来获取数据的 JSON 接口,一旦来源不匹配,就会被卡住。

最常见的跨域场景

比如你在本地写了个 HTML 页面,文件路径是 file:///Users/xxx/index.html,想通过 JavaScript 调用 https://api.weather.com 的接口查天气,一运行就发现失败了。或者你在 localhost:3000 开发前端,后端服务跑在 localhost:8080,看似都在本机,但端口不同也算跨域。

这时候你会发现,请求其实发出去了,服务器也返回了数据,但浏览器就是不让 JS 拿到响应内容。这正是跨域拦截的核心机制——请求能发,响应被拦。

方法一:CORS(跨域资源共享)

最标准的解决方式是让服务器配合开启 CORS。只要后端在响应头里加上 Access-Control-Allow-Origin,告诉浏览器“我允许这个域名来调我”,问题就解决了。

比如后端设置:

Access-Control-Allow-Origin: http://localhost:3000

或者开放给所有来源(慎用):

Access-Control-Allow-Origin: *

如果你有权限改后端代码,Spring Boot 里加个 @CrossOrigin 注解,Node.js 的 Express 加个 cors 中间件,就能搞定。但如果你对接的是第三方接口,人家没开 CORS,这条路就行不通了。

方法二:JSONP(只支持 GET)

这是老派但依然有效的办法。利用 <script> 标签不受跨域限制的特点,把数据包装成函数调用的形式返回。

前端这么写:

<script>
function handleData(data) {
console.log('拿到数据:', data);
}
</script>
<script src="https://api.example.com/user?callback=handleData"></script>

服务器需要返回:

handleData({"id": 1, "name": "张三"});

注意,JSONP 只能发 GET 请求,不能传自定义头,也不支持 POST,所以适用范围有限。

方法三:代理转发

开发环境下最实用的方法。比如你用 Webpack 或 Vite,可以在本地配置一个代理,把 /api 开头的请求自动转到目标服务器。

Vite 配置示例:

export default {
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
}
}
}
}

这样你的请求从 /api/user 变成了向本地服务器发请求,再由本地代理转发出去,绕过了浏览器的跨域检查。上线后可以让 Nginx 做类似转发。

方法四:浏览器临时禁用安全策略(仅测试用)

有时候只是想快速验证接口能不能通,可以临时启动浏览器时不检查跨域。比如 Chrome:

chrome --disable-web-security --user-data-dir=/tmp/chrome-temp

注意:这会关闭所有安全限制,只能用于测试,千万别日常使用。

别忘了预检请求(Preflight)

当你发送带有自定义头或非简单方法(如 PUT、DELETE)的请求时,浏览器会先发一个 OPTIONS 请求探路,叫“预检请求”。服务器必须正确响应这个 OPTIONS 请求,返回允许的方法和头信息,真正的请求才能继续。

常见的错误是后端没处理 OPTIONS,导致跨域失败。记得确保服务器对 OPTIONS 返回 200,并带上:

Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization