代码之家  ›  专栏  ›  技术社区  ›  Ranjith Varatharajan

使用IMDB api会导致错误的json

  •  0
  • Ranjith Varatharajan  · 技术社区  · 7 年前

    我有一个使用IMDB api的简单程序,我得到了结果,但它显示为错误,因为结果不是结构化json。

    电影服务。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;
      }
    }
    

    addmovie。组成部分ts

       private _filterMovies(value: string) {
        this.movieService.getMovie(value).subscribe(
          movies => {
            console.log(movies);
            return movies;
          }
        );
      }
    
      ngOnInit() {
        this.addMovieForm.get('movie').valueChanges.subscribe(val => {
          this._filterMovies(val)
        });
      }
    

    我犯了这样的错误

    enter image description here

    响应是错误的json。如何在收到json时格式化json?如何解决这个问题?任何线索都会有帮助。

    0 回复  |  直到 7 年前
        1
  •  0
  •   djs Evandro Pomatti    7 年前

    结果并非如此 JSON ,而是 JSONP 。它本质上是返回一个试图执行指定回调方法的脚本。

    而不是 http.get() 你应该打电话 http.jsonp(url, "imbdIgnoresThisParam") .

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

    1. 使用闭包来调用/设置你的 MovieService 。这将导致对API的调用抛出错误,因为Angular framework的回调不会按预期调用。你可以忽略这个错误。
    2. 尝试调用预期的角度回调, ng_jsonp_callback_<idx> 。这将阻止API调用抛出,但可能不可靠。回调名称是动态的,并随时间递增 jsonp() 呼叫你可以试着追踪 jsonp() 在应用程序中调用。当然,框架可能会改变并打破这个解决方案。对的并发调用 getMovie() 可能会中断,因为下一个可能会踩到窗口上的上一个回调。小心使用!

    在typescript中,您的 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!
        });
    }
    

    编辑角度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项目,所以很难说这些版本中的回调是否有任何差异。

    有点像黑客,但希望能有所帮助!

    推荐文章