- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
以下网址解释了如何在 Angular 4 中使用 http 拦截器:https://angular.io/guide/http#intercepting-all-requests-or-responses
但是,我想知道是否有任何方法可以选择是否使用拦截器?或者选择使用哪一组拦截器?我想实现一组身份验证拦截器,但是,我不希望在用户访问诸如 login
、signup
和 forget- 之类的内容时应用这些拦截器-不需要用户认证的密码
。
如果需要,我只需要将一个干净的 HttpClient
实例注入(inject)到我的服务中。我不喜欢我只能使用被所有拦截器污染的 HttpClient
的单个全局实例的方式。
最佳答案
我有同样的要求,并提出了以下解决方案。
在模块中,我使用 token “提供”一个 HttpClient,如下所示。
export const HTTP_NOAUTH = new InjectionToken("http_noauth");
...
providers: [...,
{
provide: HTTP_NOAUTH,
deps: [HttpBackend],
useFactory: (handler: HttpBackend) => {
return new HttpClient(handler);
}
},
{
provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor,
multi: true
}],
...
然后,当我注入(inject) HttpClient 并且不想使用 AuthHttpInterceptor 时,我指定“@Inject(HTTP_NOAUTH)”。
@Injectable({
providedIn: 'root',
})
export class SomeService {
constructor(@Inject(HTTP_NOAUTH) private http: HttpClient) {
...
到目前为止我发现的一个主要漏洞(可能还有更多)是它是一个全有或全无的解决方案。它要么拥有所有拦截器,要么一个都没有。可以在 token 提供的条目中注入(inject)单独的拦截器,但我还没有深入研究。
更新:
我现在可以为 HttpClient 的每个配置选择要排除的拦截器,如下所示。
import { Observable } from 'rxjs';
import { HttpHandler, HttpEvent, HttpRequest, HttpInterceptor, HttpBackend, HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';
import { Injector, InjectionToken } from '@angular/core';
export const provideTokenizedHttpClient = (token: InjectionToken<string>, options: { excludes: Function[] } = { excludes: [] }) => {
return {
provide: token,
deps: [HttpBackend, Injector],
useFactory: (backend: HttpBackend, injector: Injector) => {
return new HttpClient(
new HttpDynamicInterceptingHandler(backend, injector, options)
);
}
}
}
class HttpInterceptorHandler implements HttpHandler {
constructor(private next: HttpHandler, private interceptor: HttpInterceptor) { }
handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
return this.interceptor.intercept(req, this.next);
}
}
class HttpDynamicInterceptingHandler implements HttpHandler {
private chain: any = null;
constructor(private backend: HttpBackend, private injector: Injector, private options: { excludes: Function[] } = { excludes: [] }) { }
public handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
if (this.chain === null) {
const interceptors = this.injector.get(HTTP_INTERCEPTORS, [])
.filter(entry => !this.options.excludes.includes(entry.constructor));
this.chain = interceptors.reduceRight((next, interceptor) => {
return new HttpInterceptorHandler(next, interceptor);
}, this.backend);
}
return this.chain.handle(req);
}
}
现在在我的供应商中,我只需使用以下内容:
providers: [...
provideTokenizedHttpClient(HTTP_NOAUTH, { excludes: [AuthHttpInterceptor] }),
{
provide: HTTP_INTERCEPTORS,
useClass: AppBusyHttpInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor,
multi: true
}],
InjectionToken 的创建和它在@Inject 装饰器上的使用是相同的。
关于angular - 可选地在 Angular 4 中应用 http 拦截器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46751111/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!