【发布时间】:2017-05-17 00:07:39
【问题描述】:
我正在尝试通过扩展默认 Http 类并覆盖 request() 方法以附加特定的授权自定义标头,从而将自定义标头添加到 Angular (v4) 应用程序中的请求。该类如下所示:
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptionsArgs, Request, Response, ConnectionBackend, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { AuthToken } from '../authentication/auth-token';
@Injectable()
export class ZHttpService extends Http {
private HEADER_AUTHORIZATION: string = 'X-Z-AUTHORIZATION';
constructor(protected backend: ConnectionBackend, protected defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
private setCustomHeaders(options?: RequestOptionsArgs):RequestOptionsArgs{
if(!options) {
options = new RequestOptions({});
}
let authTokenJSON = localStorage.getItem("z-auth-token");
if(authTokenJSON) {
if (!options.headers) {
options.headers = new Headers();
}
let authToken: AuthToken = JSON.parse(authTokenJSON);
options.headers.append(this.HEADER_AUTHORIZATION, `${authToken.token}`);
}
return options;
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
options = this.setCustomHeaders(options);
return super.request(url, options).catch(this.catchAuthError(this));
}
private catchAuthError (self: ZHttpService) {
return (res: Response) => {
console.log(res);
if (res.status === 401 || res.status === 403) {
console.log(res);
}
return Observable.throw(res);
};
}
public isAuthenticated() {
return localStorage.getItem("z-auth-token") != null;
}
}
使用此自定义 http 服务的类只需执行以下操作(在本例中):
...
constructor (private http: ZHttpService) {}
getAccount(): Observable<Account> {
return this.http.get(this.accountUrl)
.map(this.parseAccount)
.catch(this.handleError);
}
...
正在成功检索令牌并且正在执行此代码。但是,在传出请求中,不存在自定义标头。
CORS在服务器端(DropWizard)配置如下:
// Cross Origin Policy Configuration
final FilterRegistration.Dynamic corsFilterConfig = environment.servlets().addFilter("CORS", CrossOriginFilter.class);
corsFilterConfig.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
corsFilterConfig.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
corsFilterConfig.setInitParameter(CrossOriginFilter.EXPOSED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
corsFilterConfig.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "OPTIONS,GET,PUT,POST,DELETE,HEAD");
// Cors URL Mapping
corsFilterConfig.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "*");
// Restriction to Permit Unauthenticated Preflight Responses
corsFilterConfig.setInitParameter(CrossOriginFilter.CHAIN_PREFLIGHT_PARAM, Boolean.FALSE.toString());
当从 Angular 应用程序发出请求时,会出现以下标头。
正在使用的 Angular 版本是最新的,这是 ng --version 输出。
@angular/cli: 1.0.3
node: 6.10.2
os: win32 x64
@angular/animations: 4.1.2
@angular/animations/browser: undefined
@angular/common: 4.1.2
@angular/compiler: 4.1.2
@angular/core: 4.1.2
@angular/forms: 4.1.2
@angular/http: 4.1.2
@angular/material: 2.0.0-beta.5
@angular/platform-browser: 4.1.2
@angular/platform-browser-dynamic: 4.1.2
@angular/platform-browser/animations: undefined
@angular/router: 4.1.2
@angular/cli: 1.0.3
@angular/compiler-cli: 4.1.2
我做错了什么基本的事情吗?这是Angular的错误吗?我的 DropWizard 配置不正确吗?
应该注意的是,如果我使用 PostMan 发出相同的请求(在 postman 中添加标头),则服务会按预期工作。
谢谢!
【问题讨论】:
-
ZHttpService中的 get 方法在哪里? -
您是否检查过
z-auth-token是否存在并且在您的本地存储中是否有值? -
@Supamiu 是的,console.Log() 验证方法被调用并且令牌存在并被获取。
-
@echonax 是必需的吗?我的印象是所有方法(GET、POST、PUT)都是请求的子集,在基本 Http 类中调用默认的扩展获取就足够了。不是这样吗?无论哪种方式我都会尝试。
-
@Ryan 但您在
request方法中使用了setCustomHeaders。如果你从超类调用get,超类将使用它自己的request。我错了吗? github.com/angular/angular/blob/master/packages/http/src/…
标签: angular dropwizard