我有一个使用IMDB api的简单程序,正在获取结果,但由于结果不是结构化的json,因此显示为错误。
MovieService.ts
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
addmovie.component.ts
export class MovieService {
constructor(private http:HttpClient) { }
getMovie(movie:string){
return this.http.get(this.generateURL(movie));
}
private generateURL(movie:string){
return "https://v2.sg.media-imdb.com/suggests/titles/"+movie.charAt(0)+"/"+movie+".json?callback=imdb$"+movie;
}
}
我遇到类似的错误
响应为错误的json。如何在接收时格式化json?如何解决呢?任何线索都将有所帮助。
答案 0 :(得分:0)
结果不是JSON
,而是JSONP。本质上,这是在向您返回一个试图执行指定的回调方法的脚本。
您应该致电http.get()
而不是http.jsonp(url, "imbdIgnoresThisParam")
。
然而,IMDB将忽略callback
查询字符串参数according to this answer。答案建议动态创建预期的回调函数,其名称包含要搜索的标题。在该回调中,您可以做一些不同的事情。
MovieService
中的内容。这将导致您对API的调用引发错误,因为Angular框架的回调不会如预期那样被调用。您可以忽略该错误。ng_jsonp_callback_<idx>
。这样可以防止抛出API调用,但可能不可靠。回调名称是动态的,并随每个jsonp()
调用而增加。您可以尝试跟踪应用中的jsonp()
个调用。当然,框架可能会更改并破坏此解决方案。对getMovie()
的并发调用可能会中断,因为下一个调用可能会踩到窗口上的上一个回调。谨慎使用!在打字稿中,您的getMovie()
函数和相关帮助器可能看起来像这样:
private imdbData: any = null;
private jsonpIdx = 0;
private setImdb(json: any) {
this.imdbData = json;
// or do whatever you need with this
}
getMovie(movie:string) {
// dynamically create the callback on the window.
let funcName = `imdb$${movie}`;
window[funcName] = (json: any) => {
// use the closure
this.setImdbData(json);
// or try to call the callback that Angular is expecting.
window[`ng_jsonp_callback_${this.jsonpIdx++}`](json);
}
// go get your data!
let url = this.generateURL(movie)
return this.http.jsonp(url, "ignored").subscribe((json) => {
// this happens if you successfully trigger the angular callback
console.log(json);
}, (err) => {
// this happens if the angular callback isn't called
console.log(this.imdbData); // set in closure!
});
}
为Angular 4编辑
对于Angular 4
,您似乎需要将JsonpModule
与HttpModule
一起导入。然后,您将jsonp
注入http
到服务中。对IMDB的调用将变为this.jsop.request(url).subscribe(...)
,并且您的动态回调名称也需要更改。
window[funcName] = (json: any) => {
// or try to call the callback that Angular is expecting.
window["__ng_jsonp__"][`__req${this.jsonpIdx++}`]["finished"](json);
}
我没有立即设置Angular 5或6项目,因此很难说这些版本中的回调是否有差异。
排序骇客,但希望对您有所帮助!