¿Cómo hacer una simple solicitud asíncrona de JSONP en Angular 2?

Estoy tratando de convertir el siguiente código angular 1 en Angular 2:

$http.jsonp('https://accounts.google.com/logout'); 

Debe ser una solicitud de JSONP para omitir el problema de política de CORS.

En Angular 4.3 y superior debe utilizar HttpClientModule porque el JsonpModule está en desuso.

  1. Importe HttpClientModule y HttpClientJsonpModule en su módulo.
  2. Inyecte HttpClient en su servicio.
  3. Pase la clave de callback como segundo argumento para el método 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 { } 

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'); } } 

Después de todos esos cambios, las solicitudes de JSONP en Angular 2 se pueden realizar de la siguiente manera.

  1. Importe el módulo JSONP en el archivo de definición de su módulo de aplicación

     import {JsonpModule} from '@angular/http'; @NgModule({ declarations: [ //... List of components that you need. ], imports: [ JsonpModule, //... ], providers: [ //... ], bootstrap: [AppComponent] }) 
  2. Inyecte el servicio jsonp en su servicio:

     import {Jsonp} from '@angular/http'; @Injectable() export class MegaSuperService { constructor(private _jsonp: Jsonp) {} } 
  3. Realice solicitudes usando “JSONP_CALLBACK” como una propiedad de callback:

     // inside your service this._jsonp.get('/api/get?callback=JSONP_CALLBACK').map(data => { // Do stuff. }); 
  4. Como titusfx sugirió, para mapear el trabajo de la función que necesita importar, el resultado es un Observable y solo se ha definido por defecto, excepto suscribirse . Debe importar cualquier otro operador manualmente, como:

     import 'rxjs/add/operator/map'; 

o más general

  import 'rxjs/add/operator/'; 

Personalmente, solía tener esta importación en beta. Sin embargo, lo eliminé ahora, en Angular 2.0.2, y el código no se rompió. Es por eso que el paso fue inicialmente omitido. Si obtiene un error con el método de map no definido, esto sin duda ayudaría.

Si este punto final es compatible con jsonp, puede usar lo siguiente. Necesita averiguar el parámetro a usar para proporcionar la callback jsonp. En el código a continuación, lo llamo c .

Después de haber registrado JSONP_PROVIDERS al llamar a la función de bootstrap :

 import {bootstrap} from 'angular2/platform/browser' import {JSONP_PROVIDERS} from 'angular2/http' import {AppComponent} from './app.component' bootstrap(AppComponent, [ JSONP_PROVIDERS ]); 

A continuación, puede ejecutar su solicitud utilizando una instancia de la clase Jsonp que ha inyectado desde el constructor:

 import {Component} from 'angular2/core'; import {Jsonp} from 'angular2/http'; @Component({ selector: 'my-app', template: ` 
Result: {{result | json}}
` }) export class AppComponent { constructor(jsonp:Jsonp) { var url = 'https://accounts.google.com/logout&c=JSONP_CALLBACK'; jsonp.request(url, { method: 'Get' }) .subscribe((res) => { (...) }); } }

Vea esta pregunta para más detalles:

  • Necesito hacer una solicitud http a una lista de suscripción de chimpancé por correo a través de una publicación de componente