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

Posted

技术标签:

【中文标题】jqXHR - http-status-code-403(但状态码为 0)【英文标题】:jqXHR - http-status-code-403 (but the statuscode is 0) 【发布时间】:2011-08-05 10:20:54 【问题描述】:

我得到状态码 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/

提前致谢! 彼得

【问题讨论】:

现在是奖励赏金的好时机。 【参考方案1】:

服务器向 浏览器 提供 403 错误,因为您无权访问该资源,因为报告了错误消息(“所请求用户的收藏夹不公开。”) .

但是,在 jsFiddle 示例中,服务器甚至没有获取请求。

您不得发出跨浏览器的 AJAX 请求。这称为same-origin policy。出于安全原因,防止恶意编码人员在您不知情的情况下做出不愉快的事情。这是一个生硬的工具,但却是一个有效的工具。

当您甚至没有向服务器发送请求时,没有状态代码。这被 XMLHTTPRequest 对象(及其 jqXHR 包装器)报告为0

基本上,你不能在浏览器中做你想做的事情。

如果您需要浏览器异步访问此类数据,则需要在服务器上编写一个包装器,以从远程服务器获取信息并将其提供给浏览器。有一种解决方法(称为 JSONP – JSON with Padding)但我不相信 YouTube 支持它。


编辑:根据gradbot's answer,可以通过将代码更改为将dataType 设置为jsonp 来执行JSONP 请求。

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

Here's a working example using the feed gradbot suggested。请注意,结果对象被传递给处理程序,而不是 jqXHR 对象。

【讨论】:

正确,未使用 xhr,jsonp 通过将脚本元素插入 dom 来工作。 CORS(跨源资源共享)现在也是大多数最新浏览器支持的选项,以允许跨域 AJAX 请求。请参阅en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing 和 developer.mozilla.org/en-US/docs/HTTP_access_control 和 caniuse.com/#search=cors【参考方案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 确实支持它。 你可能想展示如何,因为the change you suggest 不会让事情变得更好。 更新了我的帖子。发布的原始查询需要身份验证。如果您将其粘贴到浏览器中,您将看到错误消息。这个api是公开的http://gdata.youtube.com/feeds/api/users/bernd?alt=json【参考方案3】:

403 是因为您需要为正在访问其视频的用户提供凭据。假设提供了正确的凭据,由于跨域限制,请求仍然会失败。

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

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

Youtube,实际上all Google Data API's 支持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

这是一个 working example 用于公开访问的提要。

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

【讨论】:

【参考方案4】:

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

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

其中一个最受欢迎的是 Apache 中的 mod_reverse,但根据您的服务器环境,还有其他替代方案。

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

【讨论】:

以上是关于jqXHR - http-status-code-403(但状态码为 0)的主要内容,如果未能解决你的问题,请参考以下文章

错误 jqxhr 上的 Ajax GET url

jqXHR.abort() 不取消请求但导致浏览器无响应

ajax error函数

ajax 的error参数

ajax大全

ajax设置默认值ajaxSetup()方法