golang 服务器上的 CORS 和 javascript 获取前端

Posted

技术标签:

【中文标题】golang 服务器上的 CORS 和 javascript 获取前端【英文标题】:CORS on golang server & javascript fetch frontend 【发布时间】:2017-03-21 23:32:53 【问题描述】:

我有一个 golang HTTP 服务器,代码如下:

    http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) 
    log.Println("New incoming request")

    // Authenticate
    if u, p, ok := r.BasicAuth(); ok 
      log.Println("Success")
      return
    
    log.Println("Failed")

我从一个 JS 前端调用这个 HTTP 端点,这是一个部署在端口 3000 上的反应应用程序,使用代码:

      fetch('http://localhost:8080/login', 
            method: 'post',
            headers: 
                'Authorization': 'Basic ' + btoa(authHeader),
                'Content-Type': 'application/x-www-form-urlencoded',
                'Access-Control-Allow-Origin': '*'
            ,
                body: 'A=1&B=2'
            )
            .then(function (response) 
                console.log("Authentication Success")
            )
            .catch(function (err) 
                console.log("Authentication fail", err)
            );

上述代码失败并显示以下日志。

在服务器端:

New incoming request
Failed

在浏览器上,在开发者工具日志中:

Fetch API cannot load http://localhost:8080/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

有人可以帮助解决身份验证问题吗?我不确定我是在服务器端遗漏了与 CORS 相关的内容,还是在客户端进行了错误的身份验证。有什么帮助吗?谢谢。

【问题讨论】:

请显示 cors 的 go 设置。 Access-Control-Allow-Origin 不是请求标头,它应该在服务器响应中。阅读en.wikipedia.org/wiki/… Fetch API cannot load http://localhost:8080/login. Response for preflight has invalid HTTP status code 401 是我在服务器 HTTP 处理程序中添加 w.Header().Set("Access-Control-Allow-Origin", "*") 时收到的错误消息。截至目前,服务器代码没有任何与 CORS 相关的代码,我正在寻找它。 【参考方案1】:

Access-Control-Allow-Origin: * 必须从服务器发送,而不是由客户端发送。假设你在一个标准的 net/http 处理函数中,试试这个代码:

func handler(w http.ResponseWriter, r *http.Request) 
    w.Header().Set("Access-Control-Allow-Origin", "*")
    if (r.Method == "OPTIONS") 
        w.Header().Set("Access-Control-Allow-Headers", "Authorization") // You can add more headers here if needed
     else 
        // Your code goes here
    

【讨论】:

我之前尝试过,但没有成功。我在 chrome 中得到:Fetch API cannot load http://localhost:8080/login. Response for preflight has invalid HTTP status code 401 ok 在服务器端仍然是 false。 您看到的是来自 CORS 预检检查的错误消息。请参阅 ***.com/questions/22972066/… 了解如何在 Go 中实现。 对于来自浏览器的每个请求,我在服务器端日志中只得到一个New incoming request。根据服务器端日志,没有两个请求(一个 r.POST 和另一个 r.OPTIONS)。 是的,您收到 OPTIONS 请求,之后浏览器中止。如果您正确实现了预检,浏览器将继续发送实际的 fetch 请求。 您能否更新您的代码以包含 OPTIONS 处理?无论我尝试过什么似乎都无法解决问题。我的服务器当前拥有的所有代码都在问题中。【参考方案2】:

首先 - 您需要在处理程序中使用架构:

w.Header().Set("Access-Control-Allow-Origin", "*")
    if (r.Method == "OPTIONS") 
        w.Header().Set("Access-Control-Allow-Headers", "Authorization") // You can add more headers here if needed
     else 
        // Your code goes here
    

但在此之前您需要在主“OPTIONS”中指定:

router.HandleFunc("/your_route/", your_method).Methods("POST", "OPTIONS")

这是因为您的浏览器执行了 2 个请求 - 首先检查使用某些标头的能力(例如授权),下一步是发布数据

【讨论】:

以上是关于golang 服务器上的 CORS 和 javascript 获取前端的主要内容,如果未能解决你的问题,请参考以下文章

在 Golang 中启用 CORS

CORS 授权聚合物和goapp golang

在 golang 中启用 Cors 策略

Axios 前端到 Golang 后端 CORS 问题

CORS 允许所有在同一服务器上的不同端口在 JAVA 中

从java到Go解决Gin中CORS跨域