Angular 2 http header 似乎生成或发送错误
Angular 2 http header seems to be generated or send incorrectly
我正在尝试向使用 HTTP Basic auth 进行身份验证的后端发送请求。
出于测试目的
username: user
password: password
所以正确的 header 是:
Authorization: Basic dXNlcjpwYXNzd29yZA==
我已经在 Chrome Advanced Rest Extension 中用这个 header 测试了请求,它有效:
我在 Angular2 中生成的请求是这样的:
public getCurrentCounter() {
console.log("Method getCurrentCounter() in CounterService called");
var request = this.backendURL + "counter";
var header = this.generateHeader(this.username, this.password);
console.log(header);
return this._http.get(request, {
headers: header
})
.map(res => res.json());
}
/**
* Generate HTTP header using HTTP basic Auth
*/
private generateHeader(username, password) {
var base64Creds = btoa(username + ":" + password);
var auth = 'Basic ' + base64Creds;
console.log(auth);
var authHeader = new Headers();
authHeader.append("Authorization", auth);
return authHeader;
}
我记录了生成的 Header Object,它看起来像这样:
我仍然收到这样的回复:
XMLHttpRequest cannot load http://localhost:8080/counter. Response for preflight has invalid HTTP status code 401
有人知道哪里出了问题吗?
您可能忘记导入 Headers
class。您需要在请求的基础 XHR 上将 withCredentials
属性 设置为 true
。
为此,您可以执行以下操作。首先扩展 BrowserXhr
:
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.withCredentials = true;
return <any>(xhr);
}
}
并使用扩展 class:
覆盖 BrowserXhr
提供程序
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
你能验证一下吗,但你似乎从 OPTIONS 请求中得到了这个错误?而不是 GET 请求。
问题与服务器端未启用的 CORS 有关。
您的服务必须使用 headers 回答 OPTIONS 请求,如下所示:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: [the same ACCESS-CONTROL-REQUEST-HEADERS from request]
这是一个很好的文档:http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server
也看看这个:Chrome v37/38 CORS failing (again) with 401 for OPTIONS pre-flight requests
对于 angularjs 中的基本身份验证 1.x 你能试试吗:
service.SetCredentials = function (username, password) {
var authdata = Base64.encode(username + ':' + password);
$http.defaults.headers.common = {"Access-Control-Request-Headers": "accept, origin, authorization"}; //you probably don't need this line. This lets me connect to my server on a different domain
$http.defaults.headers.common['Authorization'] = 'Basic ' + authdata; // jshint ignore:line
};
Angularjs2.x版本请看:
Angular2 - set headers for every request
我发现扩展 BaseRequestOptions 非常有趣:
class MyRequestOptions extends BaseRequestOptions {
constructor () {
super();
this.headers.append('Authorization', 'Basic ' + authdata);
}
}
希望对你有帮助
原来问题出在后端。
后端希望 OPTIONS
请求也进行基本身份验证,但是由于从 angular2 发送的 OPTIONS
请求没有身份验证 Headers,我们得到了 401响应。
限制希望在后端进行身份验证的请求类型解决了这个问题。
我正在尝试向使用 HTTP Basic auth 进行身份验证的后端发送请求。 出于测试目的
username: user
password: password
所以正确的 header 是:
Authorization: Basic dXNlcjpwYXNzd29yZA==
我已经在 Chrome Advanced Rest Extension 中用这个 header 测试了请求,它有效:
我在 Angular2 中生成的请求是这样的:
public getCurrentCounter() {
console.log("Method getCurrentCounter() in CounterService called");
var request = this.backendURL + "counter";
var header = this.generateHeader(this.username, this.password);
console.log(header);
return this._http.get(request, {
headers: header
})
.map(res => res.json());
}
/**
* Generate HTTP header using HTTP basic Auth
*/
private generateHeader(username, password) {
var base64Creds = btoa(username + ":" + password);
var auth = 'Basic ' + base64Creds;
console.log(auth);
var authHeader = new Headers();
authHeader.append("Authorization", auth);
return authHeader;
}
我记录了生成的 Header Object,它看起来像这样:
我仍然收到这样的回复:
XMLHttpRequest cannot load http://localhost:8080/counter. Response for preflight has invalid HTTP status code 401
有人知道哪里出了问题吗?
您可能忘记导入 Headers
class。您需要在请求的基础 XHR 上将 withCredentials
属性 设置为 true
。
为此,您可以执行以下操作。首先扩展 BrowserXhr
:
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.withCredentials = true;
return <any>(xhr);
}
}
并使用扩展 class:
覆盖BrowserXhr
提供程序
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
你能验证一下吗,但你似乎从 OPTIONS 请求中得到了这个错误?而不是 GET 请求。
问题与服务器端未启用的 CORS 有关。
您的服务必须使用 headers 回答 OPTIONS 请求,如下所示:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: [the same ACCESS-CONTROL-REQUEST-HEADERS from request]
这是一个很好的文档:http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server
也看看这个:Chrome v37/38 CORS failing (again) with 401 for OPTIONS pre-flight requests
对于 angularjs 中的基本身份验证 1.x 你能试试吗:
service.SetCredentials = function (username, password) {
var authdata = Base64.encode(username + ':' + password);
$http.defaults.headers.common = {"Access-Control-Request-Headers": "accept, origin, authorization"}; //you probably don't need this line. This lets me connect to my server on a different domain
$http.defaults.headers.common['Authorization'] = 'Basic ' + authdata; // jshint ignore:line
};
Angularjs2.x版本请看:
Angular2 - set headers for every request
我发现扩展 BaseRequestOptions 非常有趣:
class MyRequestOptions extends BaseRequestOptions {
constructor () {
super();
this.headers.append('Authorization', 'Basic ' + authdata);
}
}
希望对你有帮助
原来问题出在后端。
后端希望 OPTIONS
请求也进行基本身份验证,但是由于从 angular2 发送的 OPTIONS
请求没有身份验证 Headers,我们得到了 401响应。
限制希望在后端进行身份验证的请求类型解决了这个问题。