0

我正在尝试编写一个简单的 AJAX 方法来从 Vimeo 获取视频列表,而不使用 jQuery。我意识到我必须使用 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 请求而不是访问实际站点。

4

3 回答 3

1

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

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 错误请求

然后决定你从他的服务器收到什么。

于 2012-06-26T16:36:41.103 回答
1

如果您想使用 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 时,您的回调函数可以完成其工作(来自 Javacript 的简单函数调用。)

这是工作示例

于 2012-06-26T16:44:07.847 回答
0

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

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

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

于 2012-07-30T03:07:00.690 回答