无法解析通过 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