在 Golang 中启用 CORS

新手上路,请多包涵

您好我正在实施 rest api,为此我想允许提供跨源请求。

我目前在做什么:

AWS 上的 Go-server 代码:

 func (c *UserController) Login(w http.ResponseWriter, r *http.Request, ctx *rack.Context) {
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
...
...
c.render.Json(w,rsp, http.StatusOK)
return
}

本地主机上的 Ajax 代码:

 <script>
$( document ).ready(function() {
    console.log( "ready!" );
    $.ajax({
        url: 'http://ip:8080/login',
        crossDomain: true, //set as a cross domain requests
        withCredentials:false,
        type: 'post',
        success: function (data) {
            alert("Data " + data);
        },
    });
});

我在浏览器控制台上收到以下错误: XMLHttpRequest cannot load http://ip:8080/login 。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“ http://localhost:8081 ”。响应具有 HTTP 状态代码 422。

我尝试添加预检选项:

 func corsRoute(app *app.App) {
allowedHeaders := "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization,X-CSRF-Token"

f := func(w http.ResponseWriter, r *http.Request) {
    if origin := r.Header.Get("Origin"); origin != "" {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        w.Header().Set("Access-Control-Allow-Headers", allowedHeaders)
        w.Header().Set("Access-Control-Expose-Headers", "Authorization")
    }
    return
}
app.Router.Options("/*p", f, publicRouteConstraint)
}

但它不起作用。

可以做些什么来修复它。

原文由 Yash Srivastava 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 641
1 个回答

我使用 gorilla/mux 包构建 Go RESTful API 服务器,客户端使用 JavaScript 请求可以工作,

我的 Go 服务器运行在 localhost:9091 ,服务器代码:

 router := mux.NewRouter()
//api route is /people,
//Methods("GET", "OPTIONS") means it support GET, OPTIONS
router.HandleFunc("/people", GetPeopleAPI).Methods("GET", "OPTIONS")
log.Fatal(http.ListenAndServe(":9091", router))

我发现给 OPTIONS 这里很重要,否则会发生错误:

选项 http://localhost:9091/people 405(不允许的方法)

无法加载 http://localhost:9091/people :对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“ http://localhost:9092 ”。响应具有 HTTP 状态代码 405。

在允许 OPTIONS 之后效果很好。我从 这篇文章 中得到了这个想法。

此外, MDN CORS 文档 提到:

此外,对于可能对服务器数据造成副作用的 HTTP 请求方法,规范要求浏览器 “预检” 请求,使用 HTTP OPTIONS 请求方法从服务器请求支持的方法,然后在得到服务器的“批准”后, 使用实际的 HTTP 请求方法发送实际的请求。

以下是 api GetPeopleAPI 方法,注意方法中我给出注释 //Allow CORS here By * or specific origin ,我有另一个类似的答案解释 CORS 的概念在 这里

 func GetPeopleAPI(w http.ResponseWriter, r *http.Request) {

    //Allow CORS here By * or specific origin
    w.Header().Set("Access-Control-Allow-Origin", "*")

    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    // return "OKOK"
    json.NewEncoder(w).Encode("OKOK")
}

在客户端,我在 localhost:9092 上使用 html 和 javascript,javascript 将从 localhost:9092 向服务器发送请求

function GetPeople() {
    try {
        var xhttp = new XMLHttpRequest();
        xhttp.open("GET", "http://localhost:9091/people", false);
        xhttp.setRequestHeader("Content-type", "text/html");
        xhttp.send();
        var response = JSON.parse(xhttp.response);
        alert(xhttp.response);
    } catch (error) {
        alert(error.message);
    }
}

并且请求可以成功得到响应 "OKOK"

您还可以通过 Fiddler 等工具检查响应/请求标头信息。

原文由 yu yang Jian 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题