使用自定义标头获取请求失败

Posted

技术标签:

【中文标题】使用自定义标头获取请求失败【英文标题】:Get request failed with custom header 【发布时间】:2014-04-22 13:35:08 【问题描述】:

这是我的 AngularJS 代码,(如果我删除 header 选项,它可以正常工作)。

$http.get(env.apiURL()+'/banks', 
    headers: 
        'Authorization': 'Bearer '+localStorageService.get('access_token')
    
)

这是请求:

OPTIONS /banks HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:8081
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/33.0.1750.146 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: http://localhost:8081/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,vi;q=0.6

然后回应:

HTTP/1.1 404 Not Found
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: http://localhost:8081
Content-Type: text/plain; charset=utf-8
Date: Mon, 17 Mar 2014 11:05:20 GMT
Content-Length: 19

我添加了 AcceptAuthorization 标头,但请求仍然失败? 大写(我的意思是authorization vs Authorization)会导致失败吗?如果是,我怎样才能让 AngularJS 停止这样做?

if origin := req.Header.Get("Origin"); origin == "http://localhost:8081" 
    rw.Header().Set("Access-Control-Allow-Origin", origin)
    rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
    rw.Header().Set("Access-Control-Allow-Headers",
        "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")

Go服务器路由代码:

r := mux.NewRouter()
r.HandleFunc("/banks", RetrieveAllBank).Methods("GET")

http.ListenAndServe(":8080", r)

【问题讨论】:

尝试在 go 中分享您的路由代码,因为您收到 404 Not Found 好的,我已经添加了路由代码。你认为我应该在路由器中启用“OPTIONS”吗? 任何中间件试图处理授权标头?我试过你的代码(没有AngularJS),它工作正常。也许您的 ORIGIN 标头不正确。 不,我只是在修改后发送!你如何测试它? 啊,好的,问题是“OPTIONS”方法没有处理程序。谢谢你的时间:) 【参考方案1】:

好的,问题是因为我要处理“OPTIONS”请求(为了使 CORS 浏览器首先发送预检 OPTIONS 请求,然后如果被服务器接受,则发送“真实”请求)。 我只需要修改我的 Go 服务器(见评论):

func main() 
    r := mux.NewRouter()
    r.HandleFunc("/banks", RetrieveAllBank).Methods("GET")
    http.ListenAndServe(":8080", &MyServerr)


type MyServer struct 
    r *mux.Router


func (s *IMoneyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) 
    if origin := req.Header.Get("Origin"); origin == "http://localhost:8081" 
        rw.Header().Set("Access-Control-Allow-Origin", origin)
        rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        rw.Header().Set("Access-Control-Allow-Headers",
            "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
    
    // Stop here if its Preflighted OPTIONS request
    if req.Method == "OPTIONS" 
        return
    
    // Lets Gorilla work
    s.r.ServeHTTP(rw, req)

【讨论】:

只是想说,感谢您发布此答案,我不久前将其添加为***.com/questions/12830095/… 的答案,因为除此之外所有其他人都失败了,人们更有可能通过谷歌遇到该线程 很高兴能帮上忙 :) 我在NodeJS中以类似的方式解决了这个问题,基本上只是跳出了Auth过滤器。这很 hacky,但我认为这需要完成,这取决于 OPTIONS 在浏览器中的工作方式。

以上是关于使用自定义标头获取请求失败的主要内容,如果未能解决你的问题,请参考以下文章

芝加哥老板的 simple_bridge 可以获取请求自定义标头吗?

获取 API、自定义请求标头、CORS 和跨域重定向

在响应中的每个获取请求之前附加自定义标头

如何使用 python 请求模块创建自定义标头

AJAX 使用 CORS 获取自定义响应标头

即使使用自定义标头,如何禁用预检请求