如何在Angular 2中创建一个简单的JSONP异步请求?

nun*_*uda 35 jsonp asynchronous xmlhttprequest typescript angular

我正在尝试将以下Angular 1代码转换为Angular 2:

$http.jsonp('https://accounts.google.com/logout');
Run Code Online (Sandbox Code Playgroud)

它必须是JSONP请求才能跳过CORS策略问题.

Ete*_*ght 67

在所有这些重大更改之后,Angular 2中的JSONP请求可以通过以下方式进行.

  1. 在应用程序模块的定义文件中导入JSONP模块

    import {
        HttpClientModule,
        HttpClientJsonpModule
    } from '@angular/common/http';
    
    @NgModule({
    declarations: [
        //... List of components that you need.
    ],
    imports: [
        HttpClientModule,
        HttpClientJsonpModule,
        //...
    ],
    providers: [
        //...
    ],
    bootstrap: [AppComponent]
    })
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将jsonp服务注入您的服务:

    import {Injectable} from '@angular/core';
    import {HttpClient} from '@angular/http';
    import 'rxjs/add/operator/map';
    
    @Injectable()
    export class MegaSuperService {
       constructor(private _http: HttpClient) {}
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用"JSONP_CALLBACK"作为回调属性发出请求:

    // inside your service
    this._http.jsonp('/api/get', 'callback').map(data => {
    // Do stuff.
    });
    
    Run Code Online (Sandbox Code Playgroud)
  4. 正如titusfx建议的那样,为了映射您需要导入的函数工作,结果是一个Observable,并且除了subscribe之外只默认定义.您需要手动导入任何其他操作员,如:

    import {JsonpModule} from '@angular/http';
    
    @NgModule({
    declarations: [
        //... List of components that you need.
    ],
    imports: [
        JsonpModule,
        //...
    ],
    providers: [
        //...
    ],
    bootstrap: [AppComponent]
    })
    
    Run Code Online (Sandbox Code Playgroud)

或者更一般

import {Injectable} from '@angular/core';
import {Jsonp} from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class MegaSuperService {
   constructor(private _jsonp: Jsonp) {}
}
Run Code Online (Sandbox Code Playgroud)

就个人而言,我曾经在测试中使用此导入.但是我现在在Angular 2.0.2中删除它,代码没有破坏.这就是最初省略该步骤的原因.如果你得到一个错误的__CODE__方法未定义,这肯定会有所帮助.

  • 任何想法为什么这个"完全相同的代码"可以抛出一个`EXCEPTION:响应状态:200 Ok for URL:null`,永远不会进入`map`函数? (5认同)

Cou*_*son 23

Angular 4.3及更高版本中,您应该使用HttpClientModule,因为不推荐使用JsonpModule.

  1. HttpClientModuleHttpClientJsonpModule导入您的模块.
  2. HttpClient注入您的服务.
  3. 将回调密钥作为方法的第二个参数传递jsonp.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// Import relevant http modules
import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';

import { AppComponent } from './app.component';

import { ExampleService } from './example.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    // Import relevant http modules
    HttpClientModule,
    HttpClientJsonpModule
  ],
  providers: [ExampleService],
  bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

example.service.ts

import { Injectable } from '@angular/core';
// Import HttpClient class
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ExampleService {

  // Inject HttpClient class
  constructor(private http: HttpClient) { }

  getData() {
    const url = "https://archive.org/index.php?output=json&callback=archive";

    // Pass the key for your callback (in this case 'callback')
    // as the second argument to the jsonp method
    return this.http.jsonp(url, 'callback');
  }
}
Run Code Online (Sandbox Code Playgroud)


Thi*_*ier 11

如果此端点符合jsonp,则可以使用以下命令.您需要找出用于提供jsonp回调的参数.在下面的代码中,我称之为c.

JSONP_PROVIDERS调用bootstrap函数后注册后:

import {bootstrap} from 'angular2/platform/browser'
import {JSONP_PROVIDERS} from 'angular2/http'
import {AppComponent} from './app.component'

bootstrap(AppComponent, [ JSONP_PROVIDERS ]);
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用Jsonp从构造函数中注入的类的实例来执行请求:

import {Component} from 'angular2/core';
import {Jsonp} from 'angular2/http';

@Component({
  selector: 'my-app',
  template: `
    <div>
      Result: {{result | json}}
    </div>
  `
})
export class AppComponent {
  constructor(jsonp:Jsonp) {
    var url = 'https://accounts.google.com/logout&c=JSONP_CALLBACK';
    jsonp.request(url, { method: 'Get' })
     .subscribe((res) => {
       (...)
     });
  }
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此问题:


Eri*_*ton 1

对于 Angular 15 的独立组件 API,请使用withJsonpSupport()

bootstrapApplication(AppComponent, {
  providers: [provideHttpClient(withJsonpSupport())],
});
Run Code Online (Sandbox Code Playgroud)