【问题标题】:CORS problem,using axios,how can this be possible?CORS问题,使用axios,这怎么可能?
【发布时间】:2022-04-21 11:09:55
【问题描述】:

我使用 gin 作为我的后端,这是我的 cors 中间件代码。

func Cors() gin.HandlerFunc {
    return func(ctx *gin.Context) {
        method := ctx.Request.Method
        if method == "OPTIONS" {
            ctx.Header("Access-Control-Max-Age", "1728000")
            ctx.Header("Access-Control-Allow-Credentials", "true")
            ctx.Header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS")
            ctx.Header("Access-Control-Allow-Headers", "Content-Type,Cookie,Authorization,Access-Control-Request-Headers,Access-Control-Request-Method,Origin,Referer,Sec-Fetch-Dest,Accept-Language,Accept-Encoding,Sec-Fetch-Mode,Sec-Fetch-Site,User-Agent,Pragma,Host,Connection,Cache-Control,Accept-Language,Accept-Encoding,X-Requested-With,X-Forwarded-For,X-Forwarded-Host,X-Forwarded-Proto,X-Forwarded-Port,X-Forwarded-Prefix,X-Real-IP,Accept")
            ctx.Header("Access-Control-Allow-Origin", ctx.Request.Header.Get("origin"))
            ctx.AbortWithStatus(http.StatusNoContent)
            return
        }
        ctx.Next()
    }
}

在前端,我使用 axios 来请求,我使用 React 来开发我的应用程序。
下面是我对 axios 的设置。

const BASE_URL = "http://localhost:8000";

axios.defaults.baseURL = BASE_URL;
axios.defaults.withCredentials = true;

我抽象了一个函数来做一个 POST 请求

async function post<T = any, D = any>(
    url: string,
    data?: T,
    headers?: AxiosRequestHeaders
): Promise<D> {
    const res = await axios.post(url, data, {
        headers: headers,
    });
    if (res.status === 200) return Promise.resolve(res.data);
    else return Promise.reject(res.statusText);
}

当我在 Chrome 上请求时很有趣。

picture

我确实得到了一个 Access-Control-Allow-Origin 标头,但它只是说我没有得到这个标头响应。

真的很奇怪,不知道怎么办。

【问题讨论】:

  • 您需要为实际请求提供一些 CORS 标头,而不仅仅是预检。 (您的浏览器发送 2 个请求,一个首先检查 CORS 标头,然后才是真正的请求)。
  • 顺便说一句,我使用的是 webpack devserver
  • @super 感谢您的评论,我知道浏览器发送了 2 个请求。为实际请求提供一些 CORS 标头是什么意思?它们不是由浏览器自动提供的吗?
  • @SnowWarrior 在Access-Control-Allow-Origin 响应标头中无条件地反映请求的来源并允许凭据是不安全的!见portswigger.net/research/…。请停下来花点时间了解您在做什么。

标签: reactjs typescript go axios cors


【解决方案1】:

你试试这个

  // CORS - cors enable
func CORS(c *gin.Context) {
    c.Header("Content-Type", "application/json")
    c.Header("Access-Control-Allow-Origin", "*")
    c.Header("Access-Control-Allow-Headers", "*")
    c.Header("Access-Control-Allow-Methods", "*")
    c.Header("Access-Control-Allow-Credentials", "true")
    if c.Request.Method == http.MethodOptions {
        c.AbortWithStatus(http.StatusNoContent)
        return
    }
    c.Next()
}

【讨论】:

    【解决方案2】:

    当来源不同时,我们需要始终将 Access-Control-Allow-Origin 标头放在响应的标头中。如果我们使用 Access-Control-Allow-Credentials,这也应该放在响应的标头中。

    中间件应该改变如下:

    func Cors() gin.HandlerFunc {
        return func(ctx *gin.Context) {
            method := ctx.Request.Method
            if method == "OPTIONS" {
                ctx.Header("Access-Control-Max-Age", "1728000")
                ctx.Header("Access-Control-Allow-Credentials", "true")
                ctx.Header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS")
                ctx.Header("Access-Control-Allow-Origin", ctx.Request.Header.Get("origin"))
                ctx.Header("Access-Control-Allow-Headers", "Content-Type,Cookie,Authorization,Access-Control-Request-Headers,Access-Control-Request-Method,Origin,Referer,Sec-Fetch-Dest,Accept-Language,Accept-Encoding,Sec-Fetch-Mode,Sec-Fetch-Site,User-Agent,Pragma,Host,Connection,Cache-Control,Accept-Language,Accept-Encoding,X-Requested-With,X-Forwarded-For,X-Forwarded-Host,X-Forwarded-Proto,X-Forwarded-Port,X-Forwarded-Prefix,X-Real-IP,Accept")
                ctx.AbortWithStatus(http.StatusNoContent)
                return
            }
            ctx.Header("Access-Control-Allow-Origin", ctx.Request.Header.Get("origin"))
            ctx.Header("Access-Control-Allow-Credentials", "true")
            ctx.Next()
        }
    }
    

    【讨论】:

    • 是的,就像那样。如果您使用 Access-Control-Allow-Credentials 包含跨域 cookie,请注意某些浏览器默认阻止此功能,因此不适用于所有客户端。
    • @super 谢谢!
    猜你喜欢
    • 2018-11-29
    • 2020-09-15
    • 2020-01-02
    • 2021-06-24
    • 2019-12-29
    • 1970-01-01
    • 2013-10-15
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多