如何使用httpclient拦截角度jsonp请求

时间:2017-11-30 12:35:18

标签: angular typescript httpclient interceptor

我有一个用于http get / post请求的拦截器。它运作得很好。

不幸的是,它不能用于我的jsonp请求/它们没有被捕获。

因此我想创建另一个实现JsonpInterceptor的拦截器。

事实上,它也不起作用。

到目前为止我做了什么:

的AppModule:

[{ 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请求吗?

3 个答案:

答案 0 :(得分:1)

我认为角度中的$_FILES可能是关键点。这是我的解决方案:

  1. 检查您的foreach ($_FILES as $key=>$value) { echo $key; # It's the key that you need } 配置,删除JsonpInterceptor
  2. 然后将NgModuleHttpClientJsonpModule添加到providers.ɵb&amp; ɵc是JsonpClientBackend{provide: ɵb, useFactory: ɵc}
  3. 的别名
  4. 然后添加JsonpCallbackContext作为最后一个HTTP_INTERCEPTORS。或者您可以使用自定义拦截器覆盖JsonpInterceptor。
  5. 希望这可以帮到你。

    2018.03.09更新:

    你可以这样做:

    jsonpCallbackContext

答案 1 :(得分:1)

您必须在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));
  }
}

答案 2 :(得分:0)

我仍然不知道如何拦截jsonp请求。到目前为止,我认为它实际上并没有多大用处,因为JSONP请求是通过将脚本标记注入页面的html中,并将请求的URL作为src参数。所以我认为不可能添加任何HTTP头。也许这就是为什么JsonpInterceptor不能用于任何JSONP调用的独立工作,而忽略了之后的所有其他拦截器。

但我至少可以在某种程度上解释这个问题。也许其他人可以扩展它以提供进一步的提示。

为了使http.jsonp方法工作,通常只需导入HttpClientJsonpModule,它将{JENpInterceptor'提供给HTTP_INTERCEPTORS令牌。 来自Angular docs的HttpClientJsonpModule注释:

@NgModule({ providers: [ JsonpClientBackend, { provide: JsonpCallbackContext, useFactory: jsonpCallbackContext }, { provide: HTTP_INTERCEPTORS, useClass: JsonpInterceptor, multi: true }, ] })

JsonpInterceptor是一个实现HttpInterceptor接口的类。 JsonpInterceptor不是一个界面(我认为你不应该implement它,而且它显然也不是为了派生和扩展而设计的。它是一个可注入的Angular服务,需要提供者和其他工作才能工作。这些内容全部包含在HttpClientJsonpModule中,并且在导入JsonpInterceptor的上下文之外,可能没有多少用例直接使用HttpClientJsonpModule

可以为HTTP_INTERCEPTORS注入令牌分配多个拦截器。然后,这些都连续应用于每个请求。 通过诸如此类的陈述 [{ provide: HTTP_INTERCEPTORS, useClass: MyCustomInterceptor, multi: true }],  你只需要在链中添加另一个拦截器。

但顺序可能很重要。

只要遇到类型为JSONP的请求,JsonpInterceptor就会结束拦截器链。在这种情况下,不会调用它之​​后的所有拦截器。因此,只有非JSONP的请求才能通过其他拦截器。

因此,确保在HttpClientJsonpModule的 JsonpInterceptor之前提供所有其他拦截器是理想的。

不幸的是我还没有办法做到这一点。

但拦截JSONP请求还有另一个问题。事实上,JSONP实际上只是一个有点标准化的“黑客”,可以绕过浏览器中的CORS安全检查。 要发出请求,会在页面中插入一个javascript标记,其中请求的网址为src参数,以便加载内容。 我认为不可能为这样的请求设置任何标头。这可能就是为什么JsonpInterceptor总是结束拦截器链的原因。另一个可能是链后的“最后一次调用”,它会产生实际请求,不能知道应该通过在页面中注入一个标记来完成它,但总是只做一个正常的请求。