jqXHR - http状态码为403(但状态码为0)

10
我收到状态码为0...但实际上是403错误代码。有人能告诉我问题出在哪里吗?
JQUERY
  var jqxhr = $.ajax({
        url: 'http://gdata.youtube.com/feeds/api/users/bernd/favorites?alt=json',
        dataType: 'json'
    }).success(function(xhr) {
        alert(xhr.status);
    }).error(function(xhr) {
        alert(xhr.status);
        return false;
    })

演示 -> http://jsfiddle.net/QFuBr/

提前感谢!
Peter


现在是颁发悬赏的好时机。 - Rein Henrichs
4个回答

19
服务器向浏览器返回403错误,因为您没有访问资源的权限,这是由于报告的错误消息("请求用户的收藏不是公共的。")引起的。
然而,在jsFiddle示例中,服务器甚至没有收到请求。
您不能进行跨浏览器的AJAX请求,这被称为同源策略。出于安全原因,防止恶意编码人员在您不知情的情况下执行不良操作。这是一个简单但有效的工具。
当您甚至没有发送请求到服务器时,就没有状态码了。XMLHTTPRequest对象(及其jqXHR包装器)将其报告为0
基本上,您无法在浏览器中做您正在尝试做的事情。
如果您需要浏览器异步访问此类数据,则需要在服务器上编写一个包装器,以从远程服务器获取信息并将其提供给浏览器。有一种解决方法(称为JSONP-带填充的JSON),但我不相信YouTube支持它。

编辑:根据gradbot的答案,通过将代码中的dataType设置为jsonp,可以进行JSONP请求。

但是,您现在将无法使用xhr.status。这是因为JSONP不使用XHR对象,因此没有可用于检查的状态。

这是一个使用gradbot建议的反馈的工作示例。请注意,结果对象传递给处理程序,而不是jqXHR对象。


正确,xhr 没有被使用,而 jsonp 通过将脚本元素插入到 dom 中来工作。 - gradbot
1
CORS(跨域资源共享)现在也是大多数最新浏览器支持的选项之一,允许跨域AJAX请求。请参见http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing和https://developer.mozilla.org/en-US/docs/HTTP_access_control和http://caniuse.com/#search=cors。 - Brandon Linton

2
你需要设置dataType: "jsonp",并且登录为你要获取收藏夹的用户。在这种情况下,我使用我的用户名grabot,弹出窗口显示成功。
如果你没有有效的cookie用于访问,则API调用将返回403和内容"Favorites of requested user are not public."
$(function() {
    var jqxhr = $.ajax({
        url: 'http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json',
        dataType: 'jsonp'
    }).success(function(data, status) {
        alert(status);
    }).error(function(xhr) {
        alert(xhr.status);
    })
});

YouTube确实支持它。 - gradbot
你可能想要展示一下如何,因为你建议的更改并没有使事情变得更好。 - lonesomeday
更新了我的帖子。原始查询需要身份验证。如果您将其粘贴到浏览器中,您将看到错误消息。此API是公共的http://gdata.youtube.com/feeds/api/users/bernd?alt=json - gradbot

1

403错误是因为您需要为正在访问的用户提供凭据。假设提供了正确的凭据,请求仍将失败,因为存在跨域限制。

在大多数情况下,状态码0表示无法将请求发送到服务器。以下是Chrome控制台日志显示的您的fiddle示例。

XMLHttpRequest无法加载http://gdata.youtube.com/feeds/api/users/bernd/favorites?alt=json。来源http://fiddle.jshell.net未被Access-Control-Allow-Origin允许。

事实上,所有Google数据API都支持JSONP,但要使用它,您必须传递一个值为json-in-scriptalt参数,并将dataType指定为jsonp。jQuery会为您提供回调参数。根据经验测试,似乎Youtube并不关心alt参数是否特别为json-in-script。只要指定了callback参数,alt参数可以只取值json

http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json&callback=foo

这里有一个可公开访问的源代码示例

$.ajax({
    url: 'http://gdata.youtube.com/feeds/mobile/videos?alt=json-in-script',
    dataType: 'jsonp',
    success: function(data) {
        // do something with data
    }
});

0

由于现代浏览器的安全限制,您无法进行跨域请求(无论是GET还是POST)。

如果您仍想从其他域获取数据,请考虑使用反向代理。您可以在服务器上安装它,并通过它发送所有请求。对于浏览器来说,它看起来仍然像是数据来自同一域。

最受欢迎的之一是Apache中的mod_reverse,但根据您的服务器环境,还有其他选择。

另一种选择是如果Google API支持,则使用JSONP。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接