如何解决“请求的资源上不存在‘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’标头”的主要内容,如果未能解决你的问题,请参考以下文章

如何解决包冲突问题

如何解决包冲突问题

如何解决ajax跨域问题

MySQL 的 10048问题,如何解决?

如何解决smartgit的冲突问题

如何解决https传输图片的问题