如何解决“请求的资源上不存在‘Access-Control-Allow-Origin’标头”
Posted
技术标签:
【中文标题】如何解决“请求的资源上不存在‘Access-Control-Allow-Origin’标头”【英文标题】:How to solve "No 'Access-Control-Allow-Origin' header is present on the requested resource" 【发布时间】:2019-05-27 20:32:48 【问题描述】:我正在 Go 中实现 REST API,为此我想允许跨源请求提供服务。
我目前在做什么:
转到服务器代码:
//handleCrossO ... This function will handle CROS
func handleCrossO(w *http.ResponseWriter)
(*w).Header().Set("Content-Type", "application/json")
(*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", "Accept,
Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token,
Authorization, Auth")
//Response ... This function will create response
func Response(w http.ResponseWriter, message string, statusCode int)
handleCrossO(&w)
w.WriteHeader(statusCode)
w.Write([]byte("\"message\":\"" + message + "\""))
我在浏览器控制台上收到以下错误:
从源“http://ip:4200”访问“http://ip:8080/config”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。
我也尝试了以下代码来检查 OPTIONS 方法:
// CheckAuthorization function check if the User is autrhorized to make calls or not
// if ssid is mising then give unauthorized error otherwise call next
func CheckAuthorization(next http.HandlerFunc) http.HandlerFunc
return func(w http.ResponseWriter, r *http.Request)
if r.Method == "OPTIONS"
//handle preflight in here
response.Response(w, "success", 200)
else
store := session.SessionStore()
session, _ := store.Get(r, utils.SessionName)
ssid := r.Header.Get("Auth")
if _, ok := session.Values[ssid]; ok
next.ServeHTTP(w, r)
else
var getTokenRes = GetTokenRes
sendResponse(w, getTokenRes, 1, "Invalid
SSID", 400)
但它不起作用。
我也尝试过允许 OPTIONS 方法:
router.HandleFunc("/network", authmiddleware.CheckAuthorization(createConfiguration)).Methods("POST", "OPTIONS")
【问题讨论】:
我遇到了 CORS 问题,我实现了自己的库。但它没有用。 Chrome一直阻止我的。我使用了github.com/rs/cors,它为我完成了这项工作。我也在从服务器端创建 cookie。除非您有 https 或相同来源的服务器端 cookie,否则 chrome 不会接受。但是,您可以从客户端创建 cookie。 我的 CORS 代码 github.com/26prajval98/GetMaid-Server/blob/master/src/GetMaid/… 您似乎在使用 gorilla/mux,如果是这种情况,我建议您使用他们的 CORS 中间件和 AllowedOrigins option 传入"*"
如果这不起作用,然后传入允许来源的列表,例如"http://ip:4200", "http://ip:8080", ...
。
...也可以看看这个SO question,你可能会发现答案很有用。
@mkopriva 我已经尝试过这种方式,但仍然没有解决我的问题。
【参考方案1】:
Preflight request 应该返回成功和标题。尝试使用如下
func setupResponse(w *http.ResponseWriter, req *http.Request)
(*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", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
func indexHandler(w http.ResponseWriter, req *http.Request)
setupResponse(&w, req)
if (*req).Method == "OPTIONS"
return
// process the request...
你也可以使用https://github.com/rs/cors
package main
import (
"net/http"
"github.com/rs/cors"
)
func main()
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request)
w.Header().Set("Content-Type", "application/json")
w.Write([]byte("\"hello\": \"world\""))
)
// cors.Default() setup the middleware with default options being
// all origins accepted with simple methods (GET, POST). See
// documentation below for more options.
handler := cors.Default().Handler(mux)
http.ListenAndServe(":8080", handler)
【讨论】:
以上是关于如何解决“请求的资源上不存在‘Access-Control-Allow-Origin’标头”的主要内容,如果未能解决你的问题,请参考以下文章