什么是跨域问题
当你在做网页开发时,比如用JavaScript从一个域名去请求另一个域名的数据,浏览器突然不让你通过,页面上出现一堆红色报错,这种情况很可能是遇到了“跨域”问题。
举个例子:你的网页地址是 http://localhost:3000,而你调用的接口是 http://api.example.com/getData,这时候浏览器出于安全考虑,默认会阻止这个请求,这就是跨域。
为什么会限制跨域
浏览器的同源策略(Same-Origin Policy)是为了保护用户安全。简单说,只有协议、域名、端口都一致,才算是“同源”。只要其中一个不一样,就被视为不同源,请求就会被拦截。
比如你登录了银行网站,如果随便一个第三方页面能偷偷请求银行接口,那账户信息就危险了。所以浏览器必须拦住这种行为。
常见的解决方式
虽然跨域是安全机制,但在实际开发中我们确实需要跨域获取数据。下面几种方法在项目里经常用到。
1. 后端设置CORS
最常用的办法是让后端在响应头中加上允许跨域的字段。比如服务端返回时带上:
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization这样浏览器看到这些头信息,就知道这个来源是被允许的,就不会拦截了。如果是自己控制的API,让后端加上对应配置就行。
2. 使用代理服务器
如果你没法改后端,或者调的是第三方接口,可以在本地开发时用代理。比如用Webpack DevServer或Vite配置代理:
server: {
proxy: {
'/api': {
target: 'http://external-api.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}这样一来,前端请求 /api/user,实际上会被转发到目标域名,而因为请求的是自己的服务器,没有跨域问题。
3. JSONP(只支持GET)
老项目里还可能看到JSONP,它是利用 <script> 标签不受跨域限制的特点,动态加载一段JS代码来获取数据。但只能发GET请求,现在用得少了。
比如:
<script src="http://api.example.com/data?callback=handleResponse"></script>后端要配合返回 handleResponse({name: 'Tom'}) 这样的格式,前端定义好 handleResponse 函数就能拿到数据。
4. Nginx反向代理
上线时也可以用Nginx做反向代理。把前端和API都代理到同一个域名下。比如用户访问 https://your-site.com,Nginx把 / 开头的走静态文件,/api 开头的转发给真实接口服务器。
配置片段:
location /api/ {
proxy_pass http://backend-server/;
proxy_set_header Host $host;
}对外看起来都是同一个域名,自然就没跨域了。
调试小技巧
遇到跨域问题,先看浏览器控制台的Network标签,点开请求看状态码和响应头。如果看到 Blocked by CORS policy,基本就是缺少响应头。
另外,开发时可以用Chrome插件临时关闭跨域检查,但这只是方便调试,不能用于生产环境。
跨域不是bug,是浏览器的安全机制。理解它的工作原理,选择合适的方法绕过限制,才能让前后端顺畅协作。