消耗IMDB API结果错误的JSON

时间:2019-03-03 02:53:51

标签: json angular typescript imdb

我有一个使用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;
  }
}

我遇到类似的错误

enter image description here

响应为错误的json。如何在接收时格式化json?如何解决呢?任何线索都将有所帮助。

1 个答案:

答案 0 :(得分:0)

结果不是JSON,而是JSONP。本质上,这是在向您返回一个试图执行指定的回调方法的脚本。

您应该致电http.get()而不是http.jsonp(url, "imbdIgnoresThisParam")

然而,IMDB将忽略callback查询字符串参数according to this answer。答案建议动态创建预期的回调函数,其名称包含要搜索的标题。在该回调中,您可以做一些不同的事情。

  1. 使用闭包来调用/设置MovieService中的内容。这将导致您对API的调用引发错误,因为Angular框架的回调不会如预期那样被调用。您可以忽略该错误。
  2. 尝试调用预期的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,您似乎需要将JsonpModuleHttpModule一起导入。然后,您将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项目,因此很难说这些版本中的回调是否有差异。

排序骇客,但希望对您有所帮助!