在 Golang 中使用 CORS

在本文中,我们定义了CORS并展示了如何在Golang中使用CORS。

$ go version
go version go1.18.1 linux/amd64

我们使用Go版本1.18。

同源政策

浏览器强制执行同源策略,该策略允许网页中的JS脚本访问其他网页中的数据,前提是两个网页都具有相同的来源。origin被定义为URL方案、主机名和端口号的组合。该策略有助于隔离潜在的恶意文档,减少可能的攻击媒介。

CORS

跨源资源共享(CORS)是一种基于HTTP标头的过程,它定义允许浏览器从哪些源加载资源。

CORS通过使用HTTPCORS标头放宽了同源策略。

请求标头:

  • Origin-表示请求来源的服务器
  • Access-Control-Request-Method-表示请求实现的HTTP方法的服务器
  • Access-Control-Request-Headers-指示请求包含的标头的服务器

响应头:

  • Access-Control-Allow-Origin-服务器允许的来源
  • Access-Control-Allow-Methods-服务器允许的以逗号分隔的方法列表
  • Access-Control-Allow-Headers-服务器允许的以逗号分隔的标头列表
  • Access-Control-Expose-Headers-允许客户端访问的以逗号分隔的标头列表响应
  • Access-Control-Max-Age-告诉浏览器缓存对预检请求的响应多长时间(以秒为单位)
  • Access-Control-Allow-Credentials

GoCORS简单示例

在以下示例中,我们在Go服务器应用程序中启用CORS。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home</title>
</head>

<body>

    <script>
        async function doRequest() {
            let url = 'http://localhost:8080/hello';
            let res = await fetch(url);

            if (res.ok) {

                let text = await res.text();

                return text;
            } else {
                return `HTTP error: ${res.status}`;
            }
        }

        doRequest().then(data => {
            document.getElementById("output").innerText = data;
        });
    </script>

    <div id="output">

    </div>

</body>

</html>

在HTML网页中,我们使用JSFetchAPI来创建GET请求。该脚本读取响应并将其设置到输出div元素中。要尝试该示例,请通过网络服务器(例如nginx)或使用实时服务器VS代码扩展加载此网页。

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {

    http.HandleFunc("/hello", HelloHandler)

    log.Println("Listening...")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func HelloHandler(w http.ResponseWriter, _ *http.Request) {

    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5501")
    w.Header().Set("Access-Control-Max-Age", "15")
    fmt.Fprintf(w, "Hello, there!")
}

HelloHandler中,我们为我们的服务器设置了CORS策略。

log.Fatal(http.ListenAndServe(":8080", nil))

该应用程序在本地主机上的8080端口上运行。要从其他来源访问此服务器的资源,必须启用它们。

w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5501")
w.Header().Set("Access-Control-Max-Age", "15")

我们启用为此服务器设置CORS策略。http://127.0.0.1:5501来源的JS脚本可以访问我们的资源。

转到CORS处理程序

github.com/rs/cors是一个第三方包,它定义了在Golang中实现跨源资源共享W3规范的net/http处理程序。

package main

import (
    "fmt"
    "net/http"

    "github.com/rs/cors"
)

func main() {

    mux := http.NewServeMux()

    cors := cors.New(cors.Options{
        AllowedOrigins: []string{"*"},
        AllowedMethods: []string{
            http.MethodPost,
            http.MethodGet,
        },
        AllowedHeaders:   []string{"*"},
        AllowCredentials: false,
    })

    mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/plain; charset=utf-8")
        fmt.Fprintln(w, "Hello there!")
    })

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

在示例中,我们使用github.com/rs/cors为我们的服务器实现CORSpolicy。我们启用两种方法:GET和POST。使用*,我们允许allorigins。

EchoCORS示例

Echo、Gin或Fiber等Go网络框架具有支持CORS策略的现成中间件。

package main

import (
    "net/http"

    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
)

var (
    words = []string{"kind", "warm", "cup", "coin", "blue"}
)

func getWords(c echo.Context) error {
    return c.JSON(http.StatusOK, words)
}

func main() {

    e := echo.New()

    e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
        AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodDelete},
    }))

    e.GET("/api/words", getWords)

    e.Logger.Fatal(e.Start(":8080"))
}

该示例使用Echo框架中的CORS中间件。

在本教程中,我们在Go中使用了CORS。

列出所有Go教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏