我尝试使用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
有什么不对?
如果查看问题中包含的标题,您会看到这是一个OPTIONS请求.这表明您正在尝试发出跨站点请求,并且浏览器的CORS(跨源资源共享)协议已启动.
您显然发出了一个GET请求,其中包含一个域(或端口号)的凭据,该域与发出请求的页面的来源不同.事实上,我们从您的标题中看到原点是端口4200(角度开发服务器的标准端口),并且请求是对端口8080(可能是Java后端?).
标准CORS协议用于浏览器通过发送OPTIONS请求进行“预检”检查,以查看是否有一个Access-Control-Allow-Origin标头返回,表明允许来源访问目的地.
如果标题返回ok,那么浏览器将发出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