Angular 4.3 HttpClient不会发送授权标头

时间:2017-08-27 02:15:16

标签: angular cors

我尝试使用Angular的HttpClient发送带有授权标头的请求,但标头未成功设置。

这是我的代码。

import {HttpClient, HttpHeaders} from '@angular/common/http';


constructor(private http: HttpClient,
            private auth: AuthService) {
}

sendRequest() {
  this.http.get(this.url, {
    headers: new HttpHeaders().set('Authorization', 'Bearer ' + this.auth.getAccessToken())
  }).subscribe(
    data => {
      console.log(data);
    },
    error => {
      console.log(error);
    }
  );
}

这里是网络调试头源。

OPTIONS /userinfo HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
Referer: http://localhost:4200/user
Accept-Encoding: gzip, deflate, br
Accept-Language: ja,en-US;q=0.8,en;q=0.6

响应标题如下。

HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Sun, 27 Aug 2017 23:45:15 GMT
Content-Length: 18

有什么不对吗?

1 个答案:

答案 0 :(得分:13)

如果查看问题中包含的标题,您会看到这是一个OPTIONS请求。这表明您正在尝试发出跨站点请求,并且浏览器的CORS(跨源资源共享)协议已启动。

您显然发出了一个GET请求,其中包含一个域(或端口号)的凭据,该域与发出请求的页面的来源不同。事实上,我们从您的标题中看到源是端口4200(角度开发服务器的标准端口),并且请求是对端口8080(可能是java后端?)。

标准CORS协议是供浏览器进行预检"检查,通过发送OPTIONS请求来查看是否有一个Access-Control-Allow-Origin标头返回,说明允许来源访问目的地。

如果标题返回正常,则浏览器将发出GET请求。如果没有,您将收到401响应。

所有这些都是由浏览器完成的,并且无法控制。

规范(https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0)表示当浏览器将OPTIONS请求作为预检的一部分发送时,它不得包含您的授权标头 - 只会在GET上发送。

所以,不 - 这里没有任何问题 - 它按预期工作。

现在,如果在此之后,您获得401并且从未发送GET,那么您必须修改服务器以发送适当的Access-Control-Allow-Origin标头以响应OPTIONS请求。

有关CORS的更多信息,请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS