Go 中 CORS 解决跨域问题

Go 中 CORS 解决跨域问题

跨域问题

跨域问题 是由浏览器的 同源策略(Same-Origin Policy) 引起的安全限制。当网页尝试访问不同源(协议、域名、端口任一不同)的资源时,浏览器会阻止该请求,除非目标服务器明确允许跨域访问。

同源策略示例

  • 同源:http://a.comhttp://a.com/api(协议、域名、端口相同)
  • 跨域:http://a.com 访问 https://a.com(协议不同)、http://a.com 访问 http://b.com(域名不同)、http://a.com:80 访问 http://a.com:8080(端口不同)

CORS(跨源资源共享)

CORS (Cross-Origin Resource Sharing)是一种 W3C 标准机制,允许服务器声明哪些外部源可以访问其资源。浏览器通过 预检请求(Preflight Request)OPTIONS 方法)验证权限,服务器需响应特定的 HTTP 头来授权。

  1. 简单请求(Simple Request)
    当请求满足以下条件时,浏览器直接发送请求,并在响应头中检查 Access-Control-Allow-Origin
    • 方法为 GETPOSTHEAD
    • 请求头仅包含允许的标头(如 AcceptContent-Type 等)
    • Content-Typetext/plainmultipart/form-dataapplication/x-www-form-urlencoded
  2. 预检请求(Preflight Request)
    对于不满足简单请求条件的请求(如 PUTDELETE 或自定义请求头),浏览器会先发送一个 OPTIONS方法的预检请求,验证服务器是否允许实际请求。

关键 HTTP 头

  • Access-Control-Allow-Origin: 允许的源(如 http://a.com*
  • Access-Control-Allow-Methods: 允许的 HTTP 方法(如 GET, POST
  • Access-Control-Allow-Headers: 允许的请求头(如 Content-Type
  • Access-Control-Allow-Credentials: 是否允许携带凭据(如 Cookies)

Go 中解决跨域的两种方式

1. 手动设置响应头(适合简单场景)

package main

import (
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    // 设置 CORS 头
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

    if r.Method == "OPTIONS" {
        w.WriteHeader(http.StatusOK)
        return
    }

    w.Write([]byte("Hello, CORS!"))
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

2. 使用 rs/cors 中间件(推荐)

package main

import (
    "net/http"
    "github.com/rs/cors"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, CORS with Middleware!"))
    })

    // 配置 CORS 中间件
    c := cors.New(cors.Options{
        AllowedOrigins:   []string{"http://localhost:3000", "https://your-app.com"},
        AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE"},
        AllowedHeaders:   []string{"Content-Type", "Authorization"},
        AllowCredentials: true,
        MaxAge:           86400, // 预检请求缓存时间(秒)
    })

    handler := c.Handler(mux)
    http.ListenAndServe(":8080", handler)
}

关键配置说明

  • AllowedOrigins:指定允许访问的域名列表,生产环境应避免使用 *
  • AllowedMethods:声明支持的 HTTP 方法。
  • AllowedHeaders:允许客户端发送的非简单头部(如自定义头)。
  • AllowCredentials:设为 true 时,前端需设置 withCredentials: true(如携带 Cookies)。
  • MaxAge:减少预检请求次数,提升性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kaf_u

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值