Go标准库net/http默认不支持跨域,因CORS是应用层约束,需开发者显式决策;可用gorilla/handlers快速启用,或手写中间件,但须正确处理OPTIONS预检、Origin校验及Credentials限制。
net/http 默认不支持跨域?Go 标准库的 http.ServeMux 和 http.Handler 完全不处理 CORS 相关响应头,浏览器发起跨域请求时,若服务端未显式返回 Access-Control-Allow-Origin 等头部,预检请求(OPTIONS)会失败,后续请求被拦截。这不是 bug,而是设计使然——CORS 是应用层协议约束,需开发者明确决策是否开放、对谁开放、允许哪些方法。
gorilla/handlers 快速启用全局 CORS最常用且稳定的方式是引入第三方中间件,gorill 提供了开箱即用的
a/handlersCORS 选项,适配标准 http.Handler 接口。
go get -u github.com/gorilla/handlers
package main
import (
"log"
"net/http"
"github.com/gorilla/handlers"
)
func main() {
http.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"msg": "ok"}`))
})
// 包裹 handler,启用 CORS
handler := handlers.CORS(
handlers.AllowedOrigins([]string{"*"}),
handlers.AllowedMethods([]string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}),
handlers.AllowedHeaders([]string{"Content-Type", "Authorization"}),
)(http.DefaultServeMux)
log.Fatal(http.ListenAndServe(":8080", handler))
}AllowedOrigins([]string{"*"}) 配合 AllowCredentials:浏览器会直接拒绝,必须指定明确域名,例如 []string{"https://example.com"}
handlers.ExposedHeaders([]string{"X-Total-Count"}) 和 handlers.AllowCredentials()
当项目极轻量或需完全控制逻辑时,可手写中间件。注意:必须显式处理 OPTIONS 预检请求,否则前端发不出 POST/PUT 等非简单请求。
OPTIONS 请求直接返回 200 并设置 CORS 头,不执行后续 handlerfunc corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "https://your-frontend.com")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
w.Header().Set("Access-Control-Expose-Headers", "X-Total-Count")
w.Header().Set("Access-Control-Allow-Credentials", "true")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
// 使用方式
http.ListenAndServe(":8080", corsMiddleware(http.DefaultServeMux))/api/data 里又调一次 w.Header().Set(...)),中间件已统一处理,重复设置无效且易出错if strings.HasPrefix(r.URL.Path, "/api/") 判断Access-Control-Allow-Origin 不能动态拼接域名常见错误是试图从 r.Header.Get("Origin") 取值后白名单校验再回写——看似灵活,实则存在安全隐患和兼容陷阱。
Access-Control-Allow-Origin: {origin}**,这等于开启任意源,形同裸奔allowedOrigins := map[string]bool{
"https://app.example.com": true,
"https://staging.example.com": true,
}
origin := r.Header.Get("Origin")
if allowedOrigins[origin] {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Credentials", "true")
}AllowedOrigins 是否含 *、是否启用了 AllowCredentials、是否漏了 OPTIONS 处理——这三个点错一个,前端就静默失败。
# js
# 前端
# git
# json
# go
# github
# cookie
# golang
# 浏览器
# app
# access
# ai
# 路由
# 中间件
# String
# if
# count
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Windows音频驱动无声音原因解析_声卡驱动错误修复步骤
如何在Golang中配置代码格式化工具_使用gofmt和goimports
如何使用Golang实现负载均衡_分发请求到多个服务节点
php删除数据怎么加限制_带where条件删除避免全删【指南】
如何使用Golang实现文件追加操作_向已有文件追加数据
mac怎么安装adb_MAC配置Android ADB开发环境【详解】
Python抽象类与接口设计_规范说明【指导】
Windows10如何更改任务栏高度_Win10解除锁定调整大小
如何使用Golang实现错误包装与传递_Golangfmt.Errorf%w使用实践
如何在Golang中使用encoding/gob序列化对象_存储和传输数据
Win11怎么开启远程桌面_Win11系统远程桌面启用开关
Win11怎么更改文件夹图标_自定义Win11文件夹外观样式【详解】
短链接怎么自定义还原php_修改解码规则适配需求【汇总】
Win11输入法选字框不见了怎么办_Win11输入法修复与重置【教程】
Windows10怎么卸载预装软件_Windows10预装软件卸载步骤【教程】
Win11如何开启系统更新 Win11开启系统更新方法【步骤】
如何在 PHP 中按相同键合并两个关联数组为二维数组
如何在Golang中捕获JSON序列化错误_Golangjson.Marshal错误处理示例
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
如何在Golang中处理JSON字段缺失_Golangjson解析字段校验方法
Go 语言标准库为何不提供泛型 Contains 方法:设计哲学与类型系统约束
如何用列表一次性对 DataFrame 的指定列应用字典映射
新手学PHP架构总混淆概念咋办_重点梳理【教程】
Win11怎么清理C盘系统日志_Win11清理系统日志文件【步骤】
Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件
php打包exe怎么传递参数_命令行参数接收方法【解答】
Linux如何申请SSL免费证书_Linux下Certbot安装与Nginx自动续期【指南】
c++中如何使用auto关键字_c++11类型推导用法说明
如何使用 Selenium 正确获取篮球参考网站球员名单元素列表
如何使用Golang sync.Map实现并发安全map_避免锁竞争
如何在Golang中捕获结构体方法错误_Golang方法返回error处理实践
Win11怎么关闭防火墙通知_屏蔽Win11安全中心安全警告弹窗【技巧】
c++如何使用std::bitset进行位图算法_c++ 快速查找与大规模数据排重【方法】
php中$this和::能混用吗_对象与静态作用域冲突解决【方法】
MAC怎么在照片中添加水印_MAC自带编辑工具文字水印叠加【方法】
如何在 PHP 单元测试中正确模拟带方法的图像处理门面(Facade)
Mac如何创建和管理多个桌面空间_Mac高效多任务处理【技巧】
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
mac怎么安装字体_MAC添加第三方字体与字体册管理【教程】
XSLT怎么生成动态的HTML属性名和标签名
VSC怎样在Linux运行PHP_Ubuntu系统配置步骤【操作】
Win11怎么设置夜间模式_Windows11显示设置蓝光过滤强度
如何在Golang中实现微服务负载均衡_Golang负载均衡策略与实现示例
Win11怎么用设置清理回收站_Win11设置清理回收站技巧【步骤】
Win11系统占用空间大怎么办 Win11深度瘦身清理指南【优化】
如何使用Golang操作指针变量_Golang解引用与赋值实践
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
Win10如何更改开机密码_Windows10登录选项更改密码
如何使用Golang读取日志文件_Golang bufio Scanner日志处理示例
Win11文件扩展名怎么显示_Win11查看文件后缀名设置【基础】
2026-01-01
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。