如何解决本地接口请求跨域 (CORS) 失败的问题
当你使用网页版工具(如 Getman)直接请求 localhost 或 127.0.0.1 上的本地服务时,经常会遇到 TypeError: Failed to fetch 的报错,并且在浏览器控制台(F12)中看到红色的 CORS(跨域资源共享)拦截警告。
Access to fetch at '***' from origin '***' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这是因为现代浏览器内置的安全策略限制了公网网页直接读取私有网络的数据。由于纯前端无法打破浏览器的安全沙箱,你需要配合以下几种方法之一来解决这个问题:
方案一:为你的本地服务开启跨域允许(最推荐)
如果你正在开发自己的本地后端服务,最规范的做法是在你的代码中显式允许跨域请求。你需要让后端在 HTTP 响应头中返回 Access-Control-Allow-Origin: *(或特定的域名)。
这里提供常见后端框架的快速配置代码:
🔹 Node.js (Express)
安装 cors 包:npm install cors
const express = require('express');
const cors = require('cors');
const app = express();
// 开启全局跨域
app.use(cors());
app.get('/api/test', (req, res) => {
res.json({ message: "跨域请求成功!" });
});
app.listen(3000);
🔹 Spring Boot (Java)
在你的 Controller 类或方法上直接添加 @CrossOrigin 注解:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin(origins = "*")
@RestController
public class MyController {
// ...
}
或者添加一个全局 CORS 配置类:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
}
}
🔹 Go (Gin)
package main
import (
"github.com/gin-gonic/gin"
)
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}
}
func main() {
r := gin.Default()
r.Use(CORSMiddleware())
r.Run(":8080")
}
🔹 Python (Django)
安装 django-cors-headers:pip install django-cors-headers
然后在 settings.py 中配置:
INSTALLED_APPS = [
...
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
CORS_ALLOW_ALL_ORIGINS = True
方案二:启动浏览器“禁用安全策略”模式(开发者调试专用)
如果你正在请求第三方的本地服务,无法修改其代码,你可以临时关闭浏览器的安全沙箱机制。
⚠️ 警告:这会降低浏览器的安全性,建议仅用于本地接口测试,测试完毕后请正常重启浏览器。
Windows
- 按
Win + R打开运行窗口。 - 输入以下命令并回车(确保关闭了所有已有的 Chrome 窗口):
chrome.exe --disable-web-security --user-data-dir="C:/ChromeDev"
macOS
- 打开“终端 (Terminal)”。
- 输入以下命令并回车:
open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
此时会弹出一个全新的 Chrome 窗口,顶部可能有一条黄色警告提示“您使用的是不受支持的命令行标记”。在这个浏览器窗口中打开网页版工具,就可以自由请求任何本地接口了。
方案三:使用本地反向代理(如 Nginx)
你可以在本地搭建一个 Nginx,通过反向代理给你的目标接口强行加上跨域允许头。
在你的 nginx.conf 中添加类似如下配置:
server {
listen 8080;
server_name localhost;
location / {
# 允许所有来源跨域
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# 代理到你的真实本地服务
proxy_pass http://127.0.0.1:3000;
}
}
启动 Nginx 后,在工具中请求 http://127.0.0.1:8080 即可。
为什么安装浏览器“跨域插件”还是不行?
你可能会想:“为什么我安装了网上的 Allow CORS 插件还是不行?”
因为专业的 HTTP 请求工具需要发送 User-Agent、Origin 等受限请求头,以及处理复杂的 OPTIONS 预检请求和 Chrome 近期引入的 PNA (Private Network Access) 限制。普通的跨域插件仅仅是简单地修改响应头,无法绕过这些浏览器底层的深度限制。
最根本的解决方式是让目标服务端本身支持跨域,或者完全关闭浏览器的安全限制进行纯净调试。