Go服务端与JS客户端交互的CORS问题解决求助
解决Go服务端与JS客户端的CORS跨域问题
问题分析
你的CORS错误根源在于:浏览器发起跨域POST请求前会先发送OPTIONS预检请求,你的服务端没有处理这个请求;另外你的Go结构体JSON标签写法有误,会导致JSON解析失败。
解决方案
步骤1:修正Go结构体的JSON标签
你的Product结构体标签缺少反引号,正确写法如下:
type Product struct { Id int `json:"id"` Desc string `json:"desc"` }
步骤2:添加CORS中间件处理跨域请求
使用gorilla/handlers库提供的CORS中间件,它会自动处理OPTIONS预检请求并设置正确的响应头:
- 先安装依赖:
go get github.com/gorilla/handlers
- 修改服务端代码,添加CORS配置:
package main import ( "encoding/json" "fmt" "github.com/gorilla/mux" "github.com/gorilla/handlers" "net/http" ) type Product struct { Id int `json:"id"` Desc string `json:"desc"` } func productsPostHandler(w http.ResponseWriter, r *http.Request) { p := &Product{} err := json.NewDecoder(r.Body).Decode(p) if err != nil { w.WriteHeader(http.StatusBadRequest) return } fmt.Println(p.Id, p.Desc) // 给客户端返回成功响应 w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{"status": "success"}) } func main() { router := mux.NewRouter() router.HandleFunc("/products", productsPostHandler).Methods("POST") // 配置CORS允许的来源、方法和头 corsOpts := handlers.CORS( handlers.AllowedOrigins([]string{"*"}), // 开发环境可设为*,生产环境指定具体域名 handlers.AllowedMethods([]string{"POST", "OPTIONS"}), handlers.AllowedHeaders([]string{"Content-Type"}), ) fmt.Println("Server is listening...") // 用CORS中间件包装路由 http.ListenAndServe(":8181", corsOpts(router)) }
步骤3:优化客户端fetch请求
添加Content-Type头,确保服务端能正确解析JSON:
fetch("http://localhost:8181/products", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ id: 1, desc: "The first product", }) }) .then(response => response.json()) .then(data => console.log(data)) .catch(err => console.error("请求错误:", err))
为什么直接加Access-Allow-Origin没用?
因为跨域POST属于复杂请求,浏览器会先发送OPTIONS预检请求,询问服务端是否允许跨域。如果服务端没有处理OPTIONS请求,直接在POST接口加头,浏览器会因为预检失败而报错。使用CORS中间件能自动处理OPTIONS请求,并设置所有必要的跨域头。
内容的提问来源于stack exchange,提问作者Илья Загородников
相关产品推荐
相关产品推荐

