如何使用httpclient拦截角度jsonp请求
Posted
技术标签:
【中文标题】如何使用httpclient拦截角度jsonp请求【英文标题】:how to intercept angular jsonp requests using httpclient 【发布时间】:2017-11-30 12:35:18 【问题描述】:我有一个用于 http get/post 请求的拦截器。效果很好。
不幸的是,它不适用于我的 jsonp 请求/它们没有被捕获。
因此我想创建另一个实现 JsonpInterceptor 的拦截器。
事实上,它也不起作用。
到目前为止我做了什么:
应用模块:
[ provide: HTTP_INTERCEPTORS, useClass: MyJsonpInterceptor, multi: true ],
MyJsonpInterceptor:
@Injectable()
export class MyJsonpInterceptor implements JsonpInterceptor
constructor(jsonp: JsonpClientBackend)
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
console.log("intercept");
有人知道,如何使用新的 httpclient 以 4/5 的角度拦截 jsonp 请求吗?
【问题讨论】:
【参考方案1】:我认为角度方面的JsonpInterceptor
可能是关键点。这是我的解决方案:
-
检查您的
NgModule
配置,删除HttpClientJsonpModule
。
然后将JsonpClientBackend
和provide: ɵb, useFactory: ɵc
添加到providers.ɵb 和ɵc 是JsonpCallbackContext
和jsonpCallbackContext
的别名
然后添加provide: HTTP_INTERCEPTORS, useClass: JsonpInterceptor, multi: true,
作为最后一个HTTP_INTERCEPTORS。或者,您可以使用自定义拦截器覆盖 JsonpInterceptor。
希望对你有帮助。
2018.03.09 更新:
你可以这样做:
@NgModule(
providers: [
provide: HTTP_INTERCEPTORS, useClass: XxxInterceptor, multi: true ,
],
)
export class XxxModule
@NgModule(
declarations: [
],
imports: [
XxxModule,
HttpClientJsonpModule,
],
providers: [
...
],
bootstrap: [AppComponent]
)
export class AppModule
【讨论】:
你能解释一下 XxxModule 的派生 JsonpInterceptor 应该是什么样子吗?我总是收到这个错误:'Class 'AuthInterceptorService' incorrectly implements interface 'JsonpInterceptor'. Types have separate declarations of a private property 'jsonp'.
用implements
(接口)和extends
尝试过。我认为extends
可能是合适的,因为 JsonpInterceptor 是一个类。我完全误解了什么吗?是否有可能从 Angular 的 JsonpInterceptor 派生并添加一些自定义逻辑,还是我们必须编写一些全新的东西?
啊,我现在明白了,我认为 JsonpInterceptor 不应该继承自。它只是一个完整且随时可用的拦截器来处理 JSONP 请求,仅此而已。与推送到 HTTP_INTERCEPTORS 多提供程序的其他拦截器一起使用(链接)。问题是这里的调用顺序。也许这就是你试图展示的?通过将 HttpClientJsonpModule 放在 XxxModule 之后,希望 jsonp 拦截器会在最后被调用。但是,这对我没有用。【参考方案2】:
你必须在HttpClientJsonpModule
之前导入JSONP拦截模块
import NgModule, Injectable from '@angular/core';
import BrowserModule from '@angular/platform-browser';
import
HttpClient,
HTTP_INTERCEPTORS,
HttpEvent,
HttpRequest,
HttpHandler,
HttpClientModule,
HttpClientJsonpModule
from '@angular/common/http'
import Observable from 'rxjs'
import AppComponent from './app.component';
@Injectable()
export class CustomInterceptor
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
return next.handle(req);
@NgModule(
providers: [
provide: HTTP_INTERCEPTORS, useClass: CustomInterceptor, multi: true
]
)
export class JsonpInterceptingModule
@NgModule(
imports: [
BrowserModule,
JsonpInterceptingModule, // Must be before the HttpClientJsonpModule
HttpClientModule,
HttpClientJsonpModule
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [
provide: HTTP_INTERCEPTORS, multi: true, useClass: CustomInterceptor
]
)
export class AppModule
constructor(http: HttpClient)
http.jsonp('https://archive.org/index.php?output=json', 'callback')
.subscribe(response => console.log(response));
【讨论】:
【参考方案3】:我还是不知道怎么拦截jsonp请求。到现在为止,我认为它实际上并没有多大用处,因为 JSONP 请求是通过将脚本标记注入页面的 html 来发出的,请求的 URL 作为 src 参数。所以我认为不可能添加任何 HTTP 标头。也许这就是为什么 JsonpInterceptor 没有被设计为除了作为任何 JSONP 调用的独立工作之外,忽略随后出现的所有其他拦截器。
但我至少可以在一定程度上解释这个问题。也许其他人可以对此进行扩展以提供进一步的提示。
为了使http.jsonp
方法正常工作,通常只需导入HttpClientJsonpModule
,它将JsonpInterceptor 提供给HTTP_INTERCEPTORS
令牌。
来自 Angular 文档的 HttpClientJsonpModule
注释:
@NgModule(
providers: [
JsonpClientBackend,
provide: JsonpCallbackContext, useFactory: jsonpCallbackContext ,
provide: HTTP_INTERCEPTORS, useClass: JsonpInterceptor, multi: true ,
]
)
JsonpInterceptor
是一个实现HttpInterceptor
接口的类。
JsonpInterceptor
不是一个接口(所以你不应该implement
它,我认为),它显然也不是为了派生和扩展而设计的。它是一个可注入的 Angular 服务,它需要一个提供者和它周围的其他东西才能工作。这东西都是捆绑在HttpClientJsonpModule
里面的,在导入HttpClientJsonpModule
的上下文之外,直接使用JsonpInterceptor
的用例可能不多。
HTTP_INTERCEPTORS
注入令牌可以分配多个拦截器。然后这些都依次应用于每个请求。
通过诸如
[ provide: HTTP_INTERCEPTORS, useClass: MyCustomInterceptor, multi: true ],
您只需将另一个拦截器添加到链中。
但顺序可能很重要。
JsonpInterceptor
将在遇到 JSONP 类型的请求时结束拦截器链。在这种情况下,不会调用它之后的所有拦截器。所以只有对非 JSONP 的请求才会通过其他拦截器。
因此,最好确保在来自HttpClientJsonpModule
的 JsonpInterceptor 之前提供所有其他拦截器。
很遗憾,我仍然没有找到方法。
但是拦截 JSONP 请求还有另一个问题。这就是事实,JSONP 实际上只是一种标准化的“黑客”,可以在浏览器中发出绕过 CORS 安全检查的请求。
为了发出请求,在页面中插入一个javascript标签,请求的url为src
参数,以获取加载的内容。
我认为不可能为这样的请求设置任何标头。所以这可能是 JsonpInterceptor 总是结束拦截器链的原因。另一个可能是链之后的“最后一次调用”,它会发出实际的请求,不知道它应该通过向页面中注入标签来完成,但总是只会做一个正常的请求。
【讨论】:
以上是关于如何使用httpclient拦截角度jsonp请求的主要内容,如果未能解决你的问题,请参考以下文章
如何使用标头、有效负载和正文制作 httpclient 获取请求?角度 API