Javascript 在不使用jQuery的情况下使用AJAX从Vimeo频道获取视频

Javascript 在不使用jQuery的情况下使用AJAX从Vimeo频道获取视频,javascript,ajax,xmlhttprequest,jsonp,vimeo,Javascript,Ajax,Xmlhttprequest,Jsonp,Vimeo,我正在尝试编写一个简单的AJAX方法,以便在不使用jQuery的情况下从Vimeo获取视频列表。我意识到我必须使用JSONP格式,因为它是一个跨域请求。但是,返回的结果始终为200 OK,并且始终为空。以下是我的方法: var httpRequest = new XMLHttpRequest(); httpRequest.open("GET", "http://vimeo.com/api/v2/channel/staffpicks/videos.json?callback=?", true);

我正在尝试编写一个简单的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。总是只有两个


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

您需要理解这些数字的含义

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.
试一试

关于身份:

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


ans然后决定您从服务器接收到什么。

如果您想使用JSONP,您需要以不同的方式使用它,否则将不允许请求通过

// 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时,回调函数可以完成它的工作(来自JavaScript的简单函数调用)


这就是问题所在。

回顾过去,这是一个相当糟糕的问题。其实有两三个问题:

  • 为什么我对Vimeo的跨域请求返回200 OK但为空
  • 为什么控制台记录的是2而不是0、1、3、4或5
  • 除了访问实际站点,我还可以如何测试AJAX请求
  • 下面是问题一和问题二的答案,分别由亚历山大和埃斯瓦尔·拉杰什·皮纳帕拉发布。问题三的答案是请求一个本地JavaScript文件

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

    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;
        }
    };
    

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

    这解释了为什么控制台不记录0或1,因为我在检查就绪状态是否已更改之前调用了open和send方法。控制台何时记录3?那会是某种错误吗?此外,状态始终为空。知道为什么吗?这解释了为什么我没有从Vimeo那里得到任何数据。我正在编写的方法需要适用于任何AJAX请求,因此如果是跨域请求,我想我需要有一个单独的方法。
    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;
        }
    };