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响应。

限制希望在后端进行身份验证的请求类型解决了这个问题。