ZetCode

Go CORS

最后修改时间 2024 年 4 月 11 日

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

同源策略

浏览器强制执行同源策略,该策略允许网页中的 JS 脚本仅在两个网页具有相同源的情况下访问其他网页中的数据。一个被定义为 URL 方案、主机名和端口号的组合。该策略有助于隔离潜在的恶意文档,从而减少可能的攻击向量。

CORS

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

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

请求标头

响应标头

Go CORS 简单示例

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

index.html
<!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 = 'https://: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 网页中,我们使用 JS Fetch API 创建 GET 请求。该脚本读取响应并将其设置为输出 div 元素。要尝试此示例,请通过 nginx 等 Web 服务器加载此网页,或使用 liveserver VS Code 扩展。

main.go
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))

该应用程序在 localhost 的 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 脚本可以访问我们的资源。

Go CORS 处理程序

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

main.go
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 为我们的服务器实现 CORS 策略。我们启用了两种方法:GET 和 POST。使用 *,我们允许所有来源。

Echo CORS 示例

Go Web 框架,如 Echo、Gin 或 Fiber,都具有可立即使用的中间件,可以启用 CORS 策略。

main.go
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 echo Web 框架

在本文中,我们已在 Go 中处理了 CORS。

作者

我叫 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出所有 Go 教程