开发者问题收集

无法解析通过 API 请求的角度中的 JSON 数据

2019-03-10
659

我试图借助 API 从 imdb 网站获取电影数据,但无法进一步处理数据。

这是我在 get 方法中传递的链接(“ https://sg.media-imdb.com/suggests/j/johnwick.json ”),打开浏览器后如下所示:

imdb$johnwick({
  "v": 1,
  "q": "johnwick",
  "d": [
    {
      "l": "John Wick: Chapter 3 - Parabellum",
      "id": "tt6146586",
      "s": "Keanu Reeves, Ian McShane",
      "y": 2019,
      "q": "feature",
      "vt": 5,
      "i": [
        "https://m.media-amazon.com/images/M/MV5BNDU3YzJlY2EtODA3NS00ZWM3LWJhYjUtZWE3MmE2YmEzNWYwXkEyXkFqcGdeQXVyNDMzMzI5MjM@._V1_.jpg",
        4050,
        6000
      ],
      "v": [
        {
          "l": "Official Trailer",
          "id": "vi3978017305",
          "s": "2:18",
          "i": [
            "https://m.media-amazon.com/images/M/MV5BNTg2YzEyNjktMmRmZi00NjU4LWIxNzYtMGE0Y2U2MDI5Y2Q1XkEyXkFqcGdeQW1yb3NzZXI@._V1_.jpg",
            1920,
            1080
          ]
        }
      ]
    },
    {
      "l": "John Wick",
      "id": "tt2911666",
      "s": "Keanu Reeves, Michael Nyqvist",
      "y": 2014,
      "q": "feature",
      "vt": 23,
      "i": [
        "https://m.media-amazon.com/images/M/MV5BMTU2NjA1ODgzMF5BMl5BanBnXkFtZTgwMTM2MTI4MjE@._V1_.jpg",
        1365,
        2048
      ],
      "v": [
        {
          "l": "Trailer #2",
          "id": "vi2273816345",
          "s": "1:00",
          "i": [
            "https://m.media-amazon.com/images/M/MV5BMjU0OTQwMjUyN15BMl5BanBnXkFtZTgwODQ5OTE4MjE@._V1_.jpg",
            640,
            480
          ]
        },
        {
          "l": "Clip",
          "id": "vi3905924889",
          "s": "0:29",
          "i": [
            "https://m.media-amazon.com/images/M/MV5BNDYwMTUwNTMyNF5BMl5BanBnXkFtZTgwNDcyMjExMzE@._V1_.jpg",
            1280,
            720
          ]
        },
        {
          "l": "John Wick",
          "id": "vi2809377049",
          "s": "4:18",
          "i": [
            "https://m.media-amazon.com/images/M/MV5BNGQ1YjYwOTUtODRkOS00NjU3LWJjZTMtOWM1MWE2YmFiN2ZjXkEyXkFqcGdeQXVyNzU1NzE3NTg@._V1_.jpg",
            480,
            360
          ]
        }
      ]
    },
    {
      "l": "John Wick: Chapter 2",
      "id": "tt4425200",
      "s": "Keanu Reeves, Riccardo Scamarcio",
      "y": 2017,
      "q": "feature",
      "i": [
        "https://m.media-amazon.com/images/M/MV5BMjE2NDkxNTY2M15BMl5BanBnXkFtZTgwMDc2NzE0MTI@._V1_.jpg",
        1328,
        2048
      ]
    },
    {
      "l": "John Williams",
      "id": "nm0002354",
      "s": "Music Department, Star Wars: Episode I - The Phantom Menace (1999)",
      "i": [
        "https://m.media-amazon.com/images/M/MV5BMjY5MTgzMTQ1NF5BMl5BanBnXkFtZTYwNDg3OTcz._V1_.jpg",
        280,
        400
      ]
    },
    {
      "l": "John Witherspoon",
      "id": "nm0936762",
      "s": "Actor, Friday (1995)",
      "i": [
        "https://m.media-amazon.com/images/M/MV5BMTM2NTg4MDcxNV5BMl5BanBnXkFtZTYwMDAxMzY0._V1_.jpg",
        317,
        400
      ]
    },
    {
      "l": "John Williams",
      "id": "nm0002369",
      "s": "Actor, Sabrina (1954)",
      "i": [
        "https://m.media-amazon.com/images/M/MV5BMTUyNDg1MTU5MV5BMl5BanBnXkFtZTcwMTgwNTUxOA@@._V1_.jpg",
        1107,
        1426
      ]
    },
    {
      "l": "John Wilder",
      "id": "nm0928588",
      "s": "Writer, Centennial (1978-1979)",
      "i": [
        "https://m.media-amazon.com/images/M/MV5BMjAxNjE0NzE1MV5BMl5BanBnXkFtZTcwNzUzNjI0NA@@._V1_.jpg",
        473,
        650
      ]
    },
    {
      "l": "John Wick Chapter 2: Wick-vizzed",
      "id": "tt7161870",
      "s": "Pedro Hollywood, J.J. Perry",
      "y": 2017,
      "q": "video",
      "i": [
        "https://m.media-amazon.com/images/M/MV5BNDNkZDI0MjktMmZiYS00ZjI4LWI3ZDctMTBhMTMyYjczMDhlXkEyXkFqcGdeQXVyODA1NjQ0OTY@._V1_.jpg",
        2000,
        3000
      ]
    }
  ]
})

这是我的 Angular 代码(服务文件):

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MovieProviderService {

  storeMovie: any[];
  constructor(private http: HttpClient) { }

   getmovies(): Observable<any>
   {
     return this.http.get('https://sg.media-imdb.com/suggests/j/johnwick.json');
   }
}

以下代码是正在提供服务的文件:

import { Component, OnInit } from '@angular/core';
import { MovieProviderService } from '../movie-provider.service';

@Component({
  selector: 'app-movie-container',
  templateUrl: './movie-container.component.html',
  styleUrls: ['./movie-container.component.scss']
})
export class MovieContainerComponent implements OnInit {

  constructor(private movieService: MovieProviderService) { }

  ngOnInit() {
     let obs = this.movieService.getmovies();
     obs.subscribe(
       (response)=>{
         const data = response.json();
         console.log(data);},
       (error)=>{console.log(error)}
     )

  }

}

它在 chrome 控制台上出现解析错误,例如无法解析位置 0 处的 JSON……

我可以看到 JSON 数据包含在里面imdb$johnwick( JSON )。如何摆脱它,或者可以告诉我一些其他好方法或我需要学习的一些主题。谢谢

2个回答

IMDB 以 JSONP 格式返回数据,因此您需要将 HttpClientModule 和 HttpClientJsonpModule 导入到您的模块中。

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 { }

model-provider.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MovieProviderService {

  storeMovie: any[];
  constructor(private http: HttpClient) { }

   getmovies(): Observable<any>
   {
     return this.http.jsonp('https://sg.media-imdb.com/suggests/j/johnwick.json', 'callback');
   }
}

希望这会有所帮助!

TheParam
2019-03-10

在 service.js 中传递选项以将响应处理为“文本”。我们希望处理服务中文本响应的重新格式化,因此我们不需要在每个组件中都考虑这一点。

使用 /(?:^.*?(\{)|\)$)/gm 替换第一个 { 和结尾 ) 之前的所有内容。 gm 是“全局”和“多行”匹配,并且仅在这些规则匹配时才会替换文本。然后,我们将用 RegExp 的第一个捕获组替换(如果没有捕获组,则 $1 变为空白字符串)。

我采用这种方法是为了确保如果源将来传递有效的 JSON,我们不会破坏/替换有效的 JSON。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MovieProviderService {

  storeMovie: any[];
  constructor(private http: HttpClient) { }

   getmovies(): Observable<string>
   {
         return this.http.get('https://sg.media-imdb.com/suggests/j/johnwick.json', { responseType: 'text' })
               .map((res) => {
                  return JSON.parse(res.replace(/(?:^.*?(\{)|\)$)/gm, "$1"));
               });
   }
}
import { Component, OnInit } from '@angular/core';
import { MovieProviderService } from '../movie-provider.service';

@Component({
  selector: 'app-movie-container',
  templateUrl: './movie-container.component.html',
  styleUrls: ['./movie-container.component.scss']
})
export class MovieContainerComponent implements OnInit {

  constructor(private movieService: MovieProviderService) { }

  ngOnInit() {
     let obs = this.movieService.getmovies();
     obs.subscribe(
       (response)=>{
         const data = response; // no longer need to call .json()

         console.log(data);},
       (error)=>{console.log(error)}
     )

  }

}
codedawi
2019-03-10