欢迎来到徐庆高(Tea)的个人博客网站
磨难很爱我,一度将我连根拔起。从惊慌失措到心力交瘁,我孤身一人,但并不孤独无依。依赖那些依赖我的人,信任那些信任我的人,帮助那些给予我帮助的人。如果我愿意,可以分裂成无数面镜子,让他们看见我,就像看见自己。察言观色和模仿学习是我的领域。像每个深受创伤的人那样,最终,我学会了随遇而安。
当前位置: 日志文章 > 详细内容

Go 跨域中间件解决CORS问题

2025年04月24日 Golang
在开发基于 web 的 api 时,尤其是前后端分离项目,**跨域问题(cors)**是前端开发人员经常遇到的“拦路虎”。本文将带你了解什么是跨域、如何在 go 中优雅地实现一

在开发基于 web 的 api 时,尤其是前后端分离项目,**跨域问题(cors)**是前端开发人员经常遇到的“拦路虎”。本文将带你了解什么是跨域、如何在 go 中优雅地实现一个跨域中间件,支持你自己的 http 服务或框架如 net/httpgin 等。

什么是跨域(cors)?

cors(cross-origin resource sharing)是浏览器的一种安全策略,它阻止一个域上的网页向另一个域发起 ajax 请求。比如,前端运行在 http://localhost:3000,后端运行在 http://localhost:8080,这就属于跨源请求。

为了安全,浏览器默认禁止这种请求,除非后端服务器明确在响应头中声明:我允许这个请求通过

go 中如何处理跨域?

在 go 中,我们可以通过**中间件(middleware)**的方式拦截请求,并给响应头添加相关的 cors 允许字段,从而让浏览器放心通信。

一、原生 net/http 实现 cors 中间件

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.handle("/", corsmiddleware(http.handlerfunc(indexhandler)))
    http.listenandserve(":8080", nil)
}

func indexhandler(w http.responsewriter, r *http.request) {
    fmt.fprintln(w, "hello from go backend")
}

func corsmiddleware(next http.handler) http.handler {
    return http.handlerfunc(func(w http.responsewriter, r *http.request) {
        // 设置 cors 响应头
        w.header().set("access-control-allow-origin", "*") // 允许所有来源
        w.header().set("access-control-allow-methods", "get, post, put, delete, options")
        w.header().set("access-control-allow-headers", "content-type, authorization")

        // 如果是预检请求,直接返回
        if r.method == "options" {
            w.writeheader(http.statusnocontent)
            return
        }

        // 继续处理请求
        next.servehttp(w, r)
    })
}

支持基本的 get、post 请求,并处理了浏览器的 预检请求(options)

二、使用 gin 框架的 cors 中间件

如果你使用的是 gin 框架,可以使用官方推荐的 github.com/gin-contrib/cors 插件:

安装依赖:

go get github.com/gin-contrib/cors

示例代码:

package main

import (
    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
    "time"
)

func main() {
    r := gin.default()

    // 使用 cors 中间件
    r.use(cors.new(cors.config{
        alloworigins:     []string{"http://localhost:3000"}, // 只允许特定域名
        allowmethods:     []string{"get", "post", "put", "delete", "options"},
        allowheaders:     []string{"origin", "content-type", "authorization"},
        exposeheaders:    []string{"content-length"},
        allowcredentials: true,
        maxage:           12 * time.hour,
    }))

    r.get("/", func(c *gin.context) {
        c.json(200, gin.h{"message": "hello from gin!"})
    })

    r.run(":8080")
}

更灵活配置,可以设置特定来源、暴露字段、是否携带 cookie 等。

小结

方式特点
原生 net/http灵活轻便,但需要手动设置和维护响应头
使用 gin 插件配置方便,支持更多高级选项,如 credentials、缓存等

跨域处理注意事项

  • 开发环境可以设置 * 允许所有源,但生产环境请限制具体域名,避免安全风险。
  • 前端使用 fetch 时,若要携带 cookie,需要设置 credentials: 'include',后端也要设置 allowcredentials: true
  • options 请求是浏览器自动发送的预检请求,必须返回 200 或 204 状态码。

写在最后

在 go 项目中实现 cors 支持并不复杂,只要你理解了浏览器的跨域行为,就可以通过中间件轻松搞定。无论你是用标准库还是 gin 框架,跨域问题都不再是“魔咒”。

到此这篇关于go 跨域中间件解决cors问题的文章就介绍到这了,更多相关go 跨域中间件 内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!