You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

第二次JSONP调用出现TypeError: __ng_jsonp__.__req0 is null问题求助

解决Angular调用Forismatic API时JSONP第二次请求报错的问题

这个错误的核心原因是你手动指定了固定的JSONP回调标识符__ng_jsonp__.__req0.finished,但Angular的JSONP机制中,每个请求的回调标识都是一次性的——第一次请求完成后,Angular会清理掉__req0对应的回调对象,第二次请求再复用这个标识符自然就找不到目标,抛出__ng_jsonp__.__req0 is null的错误。

正确的解决方式:使用Angular自带的JSONP服务

Angular已经封装了完整的JSONP请求处理逻辑,会自动帮你生成唯一的回调函数名、管理回调生命周期,完全不需要手动构造请求头和固定回调标识。具体步骤如下:

  1. 导入对应模块
    根据你的Angular版本导入对应的JSONP模块:

    // Angular 5及以下版本
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { JsonpModule } from '@angular/http';
    import { AppComponent } from './app.component';
    
    @NgModule({
      imports: [BrowserModule, JsonpModule],
      declarations: [AppComponent],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    // Angular 6+ 版本(推荐)
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';
    import { AppComponent } from './app.component';
    
    @NgModule({
      imports: [BrowserModule, HttpClientModule, HttpClientJsonpModule],
      declarations: [AppComponent],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
  2. 注入服务并重构getQuote函数
    在组件或服务中注入对应服务,然后用它发送请求:

    // Angular 5及以下版本
    import { Jsonp, Response } from '@angular/http';
    import { map } from 'rxjs/operators';
    
    // ...
    
    constructor(private jsonp: Jsonp) { }
    
    getQuote() {
      const url = "http://api.forismatic.com/api/1.0/?method=getQuote&format=jsonp&lang=en";
      return this.jsonp.request(url)
        .pipe(
          map((res: Response) => {
            const data = res.json();
            return {
              quote: data.quoteText,
              person: data.quoteAuthor || 'Unknown',
              link: data.quoteLink
            };
          })
        );
    }
    
    // Angular 6+ 版本(推荐)
    import { HttpClient } from '@angular/common/http';
    import { map } from 'rxjs/operators';
    
    // ...
    
    constructor(private http: HttpClient) { }
    
    getQuote() {
      const url = "http://api.forismatic.com/api/1.0/?method=getQuote&format=jsonp&lang=en";
      // 第二个参数是API要求的回调参数名,Forismatic用的是jsonp
      return this.http.jsonp(url, 'jsonp')
        .pipe(
          map((data: any) => {
            return {
              quote: data.quoteText,
              person: data.quoteAuthor || 'Unknown',
              link: data.quoteLink
            };
          })
        );
    }
    
  3. 调用函数的正确方式
    每次调用getQuote时订阅Observable即可,Angular会自动为每个请求生成新的回调标识,不会出现重复使用的问题:

    this.getQuote().subscribe(quote => {
      console.log(quote);
      // 这里处理返回的名言数据
    });
    

额外注意事项

  • Forismatic API的JSONP参数名是jsonp,所以在Angular 6+的http.jsonp方法中,第二个参数必须传入'jsonp',告诉Angular用这个参数名传递自动生成的回调函数名。
  • 如果遇到跨域问题,无需额外配置,Forismatic API本身支持跨域JSONP请求。

内容的提问来源于stack exchange,提问作者Haoran Zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:20:14