• Go实现CORS(跨域)


    引言

    很多时候,需要允许Web应用程序在不同域之间(跨域)实现共享资源。本文将简介跨域、CORS的概念,以及如何在Golang中如何实现CORS。

    什么是跨域

    如果两个 URL 的协议、端口(如果有指定的话)和主机都相同的话,则这两个 URL 是同源的。例如
    在这里插入图片描述

    什么是CORS

    跨域资源共享(Cross-origin resource sharing,CORS),用于让网页的受限资源能够被其他域名的页面访问的一种机制。通过该机制,页面能够自由地使用不同源的图片、样式、脚本、iframes以及视频。一些跨域的请求(特别是Ajax)常常会被同源策略(Same-origin policy)所禁止。跨源资源共享定义了一种方式,为的是浏览器和服务器之间能互相确认是否足够安全以至于能使用跨源请求(cross-origin requests)。比起纯粹的同源请求,这将更为自由和功能性的(functionality),但比纯粹的跨源请求更为安全。—维基百科

    实现原理

    跨域资源共享标准描述了,新的HTTP头部在浏览器有权限的时候,应该以如何的形式发送请求到远程URLs。虽然服务器会有一些校验和认证,但是浏览器有责任去支持这些头部以及增加相关的限制。对于能够修改数据的Ajax和HTTP请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

    Go是如何实现

    在Golang中,可以使用HTTP处理程序和中间件来实现CORS。接着我们以Gin为例

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	router := gin.Default()
    
    	// CORS中间件
    	cors := func(c *gin.Context) {
    		// 允许特定的域进行跨域请求
    		c.Writer.Header().Set("Access-Control-Allow-Origin", "http://mysite.vip")
    		// 允许特定的请求方法
    		c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
    		// 允许特定的请求头
    		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
    		// 允许携带身份凭证(如Cookie)
    		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
    		// 继续处理请求
    		c.Next()
    	}
    
    	// 应用CORS中间件到所有路由
    	router.Use(cors)
    
    	// 定义一个路由和处理器函数
    	router.GET("/hello-world", func(c *gin.Context) {
    		c.String(http.StatusOK, "Hello, World!")
    	})
    	router.Run(":8080")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    输出

    [GIN-debug] GET /hello-world --> main.main.func2 (4 handlers)
    [GIN-debug] Listening and serving HTTP on :8080
    
    • 1
    • 2

    在上例中,设置了Access-Control-Allow-Origin响应头,指定允许跨域请求的域名。您可以根据需要设置为特定域名、通配符*(允许所有域名)或动态获取请求头中的Origin值。另外,还设置了允许的请求方法、请求头以及是否允许携带身份凭证(如Cookie)。

    测试

    这里通过命令行curl来验证,如果返回结果中出现 CORS 相关的 header( ccess-Control-Allow-Origin: * < Access-Control-Allow-Methods: * < Access-Control-Allow-Headers: * < Access-Control-Expose-Headers: * < Access-Control-Max-Age: 5 ),则跨域成功。结果如下:

    #curl -i -k http://127.0.0.1:8080/hello-world
    HTTP/1.1 200 OK
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: Content-Type, Authorization
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE
    Access-Control-Allow-Origin: http://mysite.vip
    Content-Type: text/plain; charset=utf-8
    Date: Sat, 14 Oct 2023 13:42:35 GMT
    Content-Length: 13
    
    Hello, World!
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    【STM32】STM32F103C6T6标准外设库
    Python 基于PyCharm断点调试
    训练营第二十七天 | 491.递增子序列46.全排列47.全排列 II332.重新安排行程51. N皇后
    MQTT X 1.9.0 发布:开箱即用的 bench 命令,MQTT 性能测试更便捷
    基于java+SpringBoot+VUE +mysql学生信息管理系统的设计与实现
    地图双屏鼠标跟随效果
    Web前端---表格和表单
    QT DAY1
    buuctf-[RoarCTF 2019]Easy Java
    在springboot中如何开启Bean数据校验
  • 原文地址:https://blog.csdn.net/m0_73728511/article/details/133872995