【问题标题】:Get videos from Vimeo channel using AJAX without jQuery使用没有 jQuery 的 AJAX 从 Vimeo 频道获取视频
【发布时间】:2012-06-28 00:36:22
【问题描述】:

我正在尝试编写一个简单的 AJAX 方法,以在不使用 jQuery 的情况下从 Vimeo 获取视频列表。我意识到我必须使用 JSONP 格式,因为它是一个跨域请求。但是,返回的结果始终为 200 OK,并且始终为空。这是我的方法:

var httpRequest = new XMLHttpRequest();

httpRequest.open("GET", "http://vimeo.com/api/v2/channel/staffpicks/videos.json?callback=?", true);
httpRequest.send();

httpRequest.onreadystatechange = function () {
    if (httpRequest.readyState == 0) {
        console.log("0");
    }
    if (httpRequest.readyState == 1) {
        console.log("1");
    }
    if (httpRequest.readyState == 2) {
        console.log("2");
    }
    if (httpRequest.readyState == 3) {
        console.log("3");
    }
    if (httpRequest.readyState == 4 && httpRequest.status == 200) {
        console.log("4");
    }
    if (httpRequest.readyState == 4 && httpRequest.status == 404) {
        console.log("5");
    }
};

控制台记录 2,但不记录 0、1、3、4 或 5。它总是只有 2。

顺便说一句,这不一定是 Vimeo 请求。我使用 Vimeo URL 的唯一原因是因为我不知道如何测试 AJAX 请求而不是访问实际站点。

【问题讨论】:

    标签: javascript ajax xmlhttprequest jsonp vimeo


    【解决方案1】:

    回想起来,这是一个非常糟糕的问题。真的是两三个问题:

    1. 为什么我对 Vimeo 的跨域请求返回 200 OK 但它是空的?
    2. 为什么控制台记录 2 而不是 0、1、3、4 或 5?
    3. 除了访问实际站点之外,我还能如何测试 AJAX 请求?

    问题一和二的答案如下,分别由 Alexander 和 Eswar Rajesh Pinapala 发布。问题三的答案是请求一个本地的 JavaScript 文件。

    我遇到的一件其他人可能会从中受益的事情是,当 httpRequest.readyState 为 0 或 1 时,httpRequest.status 会引发异常。所以这不起作用:

    httpRequest.onreadystatechange = function () {
        alert(httpRequest.readyState + httpRequest.status);
    };​
    

    这对我有用:

    try {
        httpRequest = new XMLHttpRequest();
        console.log("0");
    
        httpRequest.open(options.method, options.url, true);
        console.log("1");
    
        httpRequest.send();
    } catch (err) {
        console.log(err.name + ': ' + err.message + ' (line ' + err.lineNumber + ')');
    
        return false;
    }
    
    httpRequest.onreadystatechange = function () {
        if (httpRequest.status === 404) {
            this.onreadystatechange = null;
    
            return false;
        }
    
        if (httpRequest.readyState === 2) {
            console.log("2");
        } else if (httpRequest.readyState === 3) {
            console.log("3");
        } else if (httpRequest.readyState === 4) {
            console.log("4");
    
            return true;
        }
    };
    

    将构造函数、open 和 send 方法包装在 try...catch 语句中的原因是,您可以捕获由错误文件名或其他原因导致的任何错误。这些将在它进入 onreadystatechange 函数之前爆炸。 onreadystatechange 属性仅在调用 send 方法后才被初始化。

    【讨论】:

      【解决方案2】:

      如果你想使用 JSONP,你需要做不同的事情,否则Cross Origin Policy 不会让请求通过。

      // Define a callback function
      var log = function(videos){
        console.log(videos);
      };
      
      // Get the JSONP response and insert it in your DOM
      var script = document.createElement('script');
      script.src = "http://vimeo.com/api/v2/channel/staffpicks/videos.json?callback=log";
      document.getElementsByTagName('head')[0].appendChild(script);
      

      通常会收到 JSON 请求:

      [ { id: 0, title: "this is a title" } ]
      

      ​ 但是,当您发送 JSONP 请求时,您会得到围绕您提供的回调函数的响应:

      log([ { id: 0, title: "this is a title" } ])
      

      当您将此响应插入 DOM 时,您的回调函数就可以完成它的工作(来自 Javacript 的简单函数调用。)

      这是working example

      【讨论】:

      • 这解释了为什么我没有从 Vimeo 获得任何数据。我正在编写的方法需要适用于任何 AJAX 请求,所以我想如果是跨域请求,我需要有一个单独的方法。
      【解决方案3】:

      您需要了解这些数字的含义。

      readyState 属性表示请求的当前状态。它返回一个 4 字节的整数。

      此属性是只读的,具有以下定义的值

      UNINITIALIZED(0) 
      The object has been created, but has not been initialized (the open method has not been called).
      LOADING(1) 
      The object has been created but the send method has not been called.
      LOADED(2) 
      The send method has been called and the status and headers are available, but the response is not.
      INTERACTIVE(3) 
      some data has been received. You can get the partial results using the responseBody and the responseText properties.
      COMPLETED(4) 
      All the data has been received, and is available.
      

      试试

      httpRequest.onreadystatechange = function () {
          alert(httpRequest.readyState + httpRequest.status);
      
      };​
      

      状态:

      200 状态正常 400 HTTP 错误 400 错误请求

      然后决定你从服务器接收什么。

      【讨论】:

      • 这解释了为什么控制台不记录 0 或 1,因为我在检查就绪状态是否已更改之前调用了 open 和 send 方法。控制台什么时候会记录 3?那会是某种错误吗?此外,状态始终为空。知道为什么吗?
      猜你喜欢
      • 1970-01-01
      • 2011-06-10
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      • 2011-02-27
      • 1970-01-01
      相关资源
      最近更新 更多