当前位置: 首页 > news >正文

Go 跨域中间件实现指南:优雅解决 CORS 问题

在开发基于 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 或 Web 开发的问题,欢迎留言讨论!

相关文章:

  • 十五、C++速通秘籍—异常处理
  • 基于Python的经济循环模型构建与可视化案例
  • Matlab添加标题title与标签lable
  • 上层 Makefile 控制下层 Makefile 的方法
  • 解释型语言和编译型语言的区别
  • 安全岗の夺命连环问:(第壹篇)从XSS到0day的灵魂拷问
  • 舵机、震动传感器、超声波使用代码
  • Qt 5.14.2 入门(四)菜单栏和工具栏的创建
  • 六、继承(三)
  • 如何用finallshell连接虚拟机
  • 前端下载文件时浏览器右上角没有保存弹窗及显示进度,下载完之后才会显示保存弹窗的问题定位及解决方案
  • PHP 拆词搜索(常用于搜索内容)
  • 从三次方程到复平面:复数概念的奇妙演进(一)
  • 多光谱相机:海洋管道漏油(溢油)监测
  • 2025蓝桥杯C++ A组省赛 题解
  • 用Python构建区块链身份认证:安全与信任的新篇章
  • ZYNQ笔记(七):程序固化(QSPI Flash)
  • OpenSSH版本的重大升级 :OpenSSH 10
  • 推流265视频,网页如何支持显示265的webrtc
  • [特殊字符] Hyperlane:为现代Web服务打造的高性能Rust文件上传解决方案
  • 泰特现代美术馆25年:那些瞬间,让艺术面向所有人
  • 北京2025年住房发展计划:供应商品住房用地240-300公顷,建设筹集保租房5万套
  • 沃旭能源因成本上升放弃英国海上风电项目,或损失近40亿元
  • 临港新片区:发布再保险、国际航运、生物医药3个领域数据出境操作指引
  • 秦洪看盘|重估叙事主题卷土重来,给A股注入新活力
  • 妻子藏匿一岁幼儿一年多不让丈夫见,法院发出人格权侵害禁令