问题描述
我正在实现 rest api,为此我想允许提供跨源请求.
Hi I'm implementing rest apis and for that I want to allow cross origin requests to be served.
我目前在做什么:
AWS 上的 Go-server 代码:
Go-server code on AWS:
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 代码:
Ajax code on localhost:
<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 无法加载 http://ip:8080/login.请求的资源上不存在Access-Control-Allow-Origin"标头.Origin 'http://localhost:8081' 因此不允许访问.响应的 HTTP 状态代码为 422.
I am getting the following error on browser console:XMLHttpRequest cannot load http://ip:8080/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access. The response had HTTP status code 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)
}
但它不起作用.
可以做些什么来修复它.
What can be done to fix it.
推荐答案
我使用 gorilla/mux
包搭建 Go RESTful API server,客户端使用 JavaScript Request 即可,
I use gorilla/mux
package to build Go RESTful API server, and client use JavaScript Request can work,
My Go Server 运行在 localhost:9091
,服务器代码:
My Go Server runs at localhost:9091
, and the Server code:
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
很重要,否则会出现错误:
I find giving OPTIONS
here is important, otherwise error will occur:
OPTIONS http://localhost:9091/people 405(不允许的方法)
无法加载 http://localhost:9091/people:对预检请求的响应未通过访问控制检查:请求的资源上不存在Access-Control-Allow-Origin"标头.Origin 'http://localhost:9092' 因此不允许访问.响应的 HTTP 状态代码为 405.
Failed to load http://localhost:9091/people: 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:9092' is therefore not allowed access. The response had HTTP status code 405.
在允许 OPTIONS
之后效果很好.我的想法来自这篇文章.
after allow OPTIONS
it works great. I get the idea from This Article.
此外,MDN CORS doc 提及:
此外,对于可能对服务器数据产生副作用的 HTTP 请求方法,规范要求浏览器对请求进行预检",使用 HTTP OPTIONS 从服务器请求支持的方法 请求方法,然后在服务器批准"后,使用实际的 HTTP 请求方法发送实际请求.
以下是 api GetPeopleAPI 方法,注意在我给出注释的方法中//Allow CORS here By * or specific origin,我有另一个类似的答案解释了这个概念CORS 此处:
Following is the api GetPeopleAPI method, note in the method I give comment //Allow CORS here By * or specific origin, I have another similar answer explaining the concept of CORS Here:
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
上使用带有 javascript 的 html,并且 javascript 将从 localhost:9092
In the client, I use html with javascript on localhost:9092
, and javascript will send request to server from 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"
.
and the request can successfully get response "OKOK"
.
您还可以通过诸如 Fiddler
之类的工具检查响应/请求标头信息.
You can also check response/request header information by tools like Fiddler
.
这篇关于在 Golang 中启用 CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!