gpt4 book ai didi

angular - 可选地在 Angular 4 中应用 http 拦截器

转载 作者:太空狗 更新时间:2023-10-29 17:39:11 25 4
gpt4 key购买 nike

以下网址解释了如何在 Angular 4 中使用 http 拦截器:https://angular.io/guide/http#intercepting-all-requests-or-responses

但是,我想知道是否有任何方法可以选择是否使用拦截器?或者选择使用哪一组拦截器?我想实现一组身份验证拦截器,但是,我不希望在用户访问诸如 loginsignupforget- 之类的内容时应用这些拦截器-不需要用户认证的密码

如果需要,我只需要将一个干净的 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com