jQuery AJAX 仅获取标题并决定是不是获取内容

Posted

技术标签:

【中文标题】jQuery AJAX 仅获取标题并决定是不是获取内容【英文标题】:jQuery AJAX fetch only headers and decide wether to get the contentjQuery AJAX 仅获取标题并决定是否获取内容 【发布时间】:2011-10-05 11:46:16 【问题描述】:

我正在制作一个基于jQuery.ajax() 的 AJAX 脚本,并且已经到了应该以某种方式检查我尝试加载的链接是 html 页面还是其他不同的东西(如 swf、图像或 zip)的地步。所以我需要以某种方式检查内容类型标头并决定是否也应该获取内容(如果它是 html)或者扔掉 ajax 调用并执行window.location = theUrl。我不想要的是获取整个文件只是为了发现它是一个 100MB 的 zip 文件。

有没有办法在请求仍在进行时“暂停”(或中止)请求并仅读取标头? HEAD call 不是一个选项,因为这样我每次都必须向服务器发出 2 个请求。

也许是某种带有 setTimeout 和低级 xhr 函数的 hack?

提前致谢! :)

编辑:尝试在请求完成之前从 setTimeout 中的 xhr 获取标头,但在获取所有数据之前它似乎不会填充它。

编辑 2:我破解了 jquery 将自身绑定到 onreadystatechange 的方法:

var xhrr = new window.XMLHttpRequest();
$.ajaxSetup(
    xhr: function()  return xhrr 
);

...
$.ajax(....);

var theirfunc = xhrr.onreadystatechange;
xhrr.onreadystatechange = function() 
    console.log('xhr state: ', xhrr.readyState);
    theirfunc();
;

所以这给了我状态 1、2、3、4 的顺序,我可以获得内容类型并成功中止。我仍在调查为什么当 jquery 本身创建 XMLHttpRequest 对象时它不起作用。如果我跳过 ajaxSetup 部分并获得 var xhrr = $.ajax(...) 然后以相同的方式绑定它将不起作用。那么我的 xhr 与 jquery 的有何不同呢?我看到他们这样做:

function createStandardXHR() 
    try 
        return new window.XMLHttpRequest();
     catch( e ) 

所以它不应该有所作为?

编辑 3:找到了! jquery 1.6 返回一个只有少量属性的假 xhr 对象,onreadystatechange 不是其中之一。

【问题讨论】:

为什么 HEAD 不是一个选项?这正是它的用途,HEAD 请求的成本应该几乎为零。 HTTP 是一个很棒的协议,如果人们开始使用它的所有功能,网络将会是一个更好的地方。 我不想再提出任何要求。也许如果我没有找到另一种方法来做到这一点...... 【参考方案1】:

我想如果你指定:

contentType: "text/html; charset=utf-8"

在您的 ajax 请求中,如果发送的数据与您指定的 MIME 类型不匹配,则请求将失败,我认为您可以这样处理。

更多信息请查看this section of the jQuery documentation

也许你也可以试试 beforeSend 参数:

    $.ajax(
  url: 'http://fiddle.jshell.net/favicon.png',
  beforeSend: function( xhr ) 
    xhr.overrideMimeType( 'text/html; charset=x-user-defined' );
  ,
  success: function( data ) 
    if (console && console.log)
      console.log( 'Sample of data:', data.slice(0,100) );
    
  
);

希望这会有所帮助。

【讨论】:

这不起作用。无论如何,服务器都会发送整个文件。我还尝试将 Accept 标头设置为 'text/html' 并且服务器仍然发送文件,就像它忽略它一样......用 Apache 和 nginx 测试 可能是 beforeSend 参数? 这对你真的有用吗?服务器响应什么?【参考方案2】:

你可能不得不破解 jQuery。我不知道如何详细执行此操作,但是...

jQuery 使用 XMLHttpRequest() 来加载数据。如果你看这里(注意页面将滚动到哪里)

http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener

您会发现以某种方式附加一个侦听器来侦听要加载的标头是可能的。然后数据将继续加载,但使用 abort() 函数可以中止它。 如果你查看 jQuery 源代码:

http://www.google.com/codesearch#LARMQtWqu54/trunk/spec/support/jquery-1.4.4.js&q=xmlhttprequest%20package:jQuery&type=cs

并搜索 xhr.send (1 match) 和 window.XMLHttpRequest (2 matches) ,您会看到 jQuery 本机不使用这些选项(注意 xhr 是 XMLHttpRequest)。但是,在 window.XMLHttpRequest 的第一个匹配项中,在 cmets 中指示您可以覆盖此对象。但是,在第二场比赛中,评论不存在,所以我不确定这是否也会被覆盖(因此你可能需要破解它才能在所有浏览器中工作)。您需要扩展 XMLHttpRequest 并修改构造函数和/或发送方法以调用其父级。以 cmets 引用的方式将该对象传递给 jQuery。

我希望你知道监听器是如何工作的,以及 javascript 中面向对象是如何工作的。

【讨论】:

非常感谢。查看我的编辑#2 另外我正在查看 jQuery 1.6.2 的源代码。他们改变了一些东西 我发现了这个dev.jquery.it/ticket/9324 以及在 cmets 中完美运行的解决方案。但是您向我指出了那个方向,所以我将您的帖子标记为答案。再次感谢:)【参考方案3】:

通过使用“HEAD”类型,jQuery 不会下载内容,它只会获取标题。

然后您可以通过在返回的 XHR 对象上使用 getResponseHeader 按名称获取它们。

$.ajax(
        type: 'HEAD',
        url: 'http://example.com/api.php',
        complete: function(xhr) 
            var contentLength = xhr.getResponseHeader('Content-Length');
        
);

您还可以使用以下命令获取所有响应标头的列表:

xhr.getAllResponseHeaders()

【讨论】:

以上是关于jQuery AJAX 仅获取标题并决定是不是获取内容的主要内容,如果未能解决你的问题,请参考以下文章

仅使用 jQuery (Ajax) 和 PHP 从 MySQL 获取最新消息? (在线聊天APP)

仅获取未隐藏的元素.. Jquery

在 jQuery UI datepicker 中仅选择特定日期(日期列表来自 AJAX)

Django AJAX 请求仅获取最后一个元素(不是 getlist 问题)

JQuery:$.ajax 不是函数

Ajax 仅适用于第一次从 php 中的 while 循环中获取数据