You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go后端对接Next.js前端时遭遇CORS跨域错误求助

解决Go后端搭配Next.js的CORS跨域问题

问题根源分析

你的代码存在两个核心问题导致CORS失败:

  • OPTIONS预请求未返回合法状态码:浏览器发送OPTIONS预请求后,需要后端返回204 No Content或200 OK状态码确认预请求通过,你的代码仅添加响应头就直接return,未明确返回状态码,浏览器无法识别预请求成功。
  • 实际请求未携带CORS响应头:你仅在OPTIONS预请求中添加了Access-Control-Allow-Origin,但实际GET/POST请求的响应里没有该头,浏览器仍会判定跨域非法。

修正后的完整代码

package main

import (
    "encoding/json"
    "log"
    "net/http"

    "github.com/gorilla/mux"
)

type ClassReturn struct {
    Errcode int         `json:"errcode"`
    Message string      `json:"message"`
    Data    interface{} `json:"data"`
}

func main() {
    r := mux.NewRouter()
    router(r)
    log.Fatal(http.ListenAndServe(":8000", r))
}

func router(r *mux.Router) {
    r.HandleFunc("/get", corsHandler(handleOutput)).Methods("GET", "OPTIONS")
    r.HandleFunc("/post", corsHandler(handleOutput)).Methods("POST", "OPTIONS")
}

func corsHandler(h http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 为所有请求(含OPTIONS和实际请求)添加基础CORS头
        w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
        w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, DELETE, PUT")
        w.Header().Set("Access-Control-Allow-Headers", "content-type")
        w.Header().Set("Access-Control-Max-Age", "86400")

        if r.Method == "OPTIONS" {
            log.Print("preflight detected: ", r.Header)
            // OPTIONS请求返回204状态码,明确告知浏览器预请求通过
            w.WriteHeader(http.StatusNoContent)
            return
        }
        // 处理实际业务请求
        h(w, r)
    }
}

func handleOutput(w http.ResponseWriter, r *http.Request) {
    // 明确响应格式为JSON,避免浏览器额外校验
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(ClassReturn{
        Errcode: 0,
        Message: "stuff endpoint",
        Data:    r.Method,
    })
}

关键修改说明

  1. 全局设置CORS头:将CORS响应头的设置移到OPTIONS判断逻辑之外,确保所有请求(包括GET/POST)都携带Access-Control-Allow-Origin等必要字段。
  2. OPTIONS请求返回状态码:添加w.WriteHeader(http.StatusNoContent),明确告知浏览器预请求已通过。
  3. 指定响应内容类型:在实际请求处理中设置Content-Type: application/json,避免部分浏览器因响应类型不明确触发额外校验。

验证步骤

重启Go后端后,打开浏览器开发者工具的网络面板:

  • 查看OPTIONS请求的响应状态码是否为204,且响应头包含Access-Control-Allow-Origin。
  • 查看GET/POST请求的响应头,确认同样存在Access-Control-Allow-Origin字段。

内容的提问来源于stack exchange,提问作者noxter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:01:00