
本文详解因端口不同导致的跨域资源共享(cors)问题,指导你在 go 后端服务中正确添加 `access-control-allow-origin` 等响应头,使前端(如 dropzone)能成功向 `http://localhost:9090/receive` 发起 post 请求。
当你通过 Nginx(运行在 https://www.php.cn/link/e91d9d8a18bc230d88e9241865958431)提供 HTML 页面,而该页面中的 Dropzone 组件尝试向 Go 服务(http://localhost:9090/receive)发起 POST 文件上传请求时,浏览器会触发 跨域资源共享(CORS)预检机制。尽管协议(http)和主机名(localhost)相同,但端口 9009 ≠ 9090,已构成不同源(RFC 6454 §5),因此浏览器拒绝响应——除非后端明确允许。
要解决此问题,需在 Go 服务的 HTTP 处理器中添加标准 CORS 响应头。以下是推荐的轻量级实现方式(无需第三方库):
func receiveHandler(w http.ResponseWriter, r *http.Request) {
// 允许指定源(开发环境可设为 "*",生产环境建议精确指定)
w.Header().Set("Access-Control-Allow-Origin", "https://www.php.cn/link/e91d9d8a18bc230d88e9241865958431")
// 允许携带凭证(如 cookies、Authorization header),若需则开启;注意:此时 Origin 不能为 "*"
// w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-Requested-With")
// 处理预检请求(OPTIONS)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
// 实际业务逻辑:处理文件上传
if r.Method != "POST" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// 示例:解析 multipart 表单
err := r.ParseMultipartForm(32 << 20) // 32MB max memory
if err != nil {
http.Error(w, "Unable to parse form", http.StatusBadRequest)
return
}
// ... 处理文件、保存等逻辑
w.WriteHeader(http.StatusOK)
w.Write([]byte("Upload received"))
}⚠️ 关键注意事项:
- Access-Control-Allow-Origin 的值*不可同时设为 `和启用Access-Control-Allow-Credentials: true**,否则浏览器将拒绝请求。若前端需携带 Cookie 或认证头,请明确指定源(如https://www.php.cn/link/e91d9d8a18bc230d88e9241865958431`);
- 必须显式处理 OPTIONS 预检请求,返回 200 OK 并带上 CORS 头,否则预检失败,后续 POST 不会发出;
- 若使用 Nginx 代理 Go 服务,也可在 Nginx 层统一添加 CORS 头(适用于多后端场景),但 Go 层控制更精准、调试更直接;
- 生产部署时,务必根据实际前端域名(如 https://app.example.com)配置 Allow-Origin,避免过度开放安全策略。
完成上述配置后,重启 Go 服务,刷新页面并重新上传,即可消除 No 'Access-Control-Allow-Origin' header is present 错误,实现跨端口安全通信。










