【问题标题】:can i remove the X-Requested-With header from ajax requests?我可以从 ajax 请求中删除 X-Requested-With 标头吗?
【发布时间】:2010-07-30 15:27:14
【问题描述】:

我想知道是否有人尝试从 jquery(或纯 JS)发出的 ajax 请求中删除“X-Requested-With”标头。有可能吗?

第二部分:你知道 Grease Monkey 的 ajax 请求是否设置了这个头吗?

谢谢

标题如下所示:

X-Requested-With XMLHttpRequest

【问题讨论】:

  • 我认为设置此标头的优点之一是您可以在服务器端脚本中检查它并确定它是否确实是 AJAX 请求,因此如何处理它?
  • w3d: 让服务器端知道您何时发出 ajax 请求的缺点是它们会阻止您在 GM 脚本中执行此操作

标签: ajax jquery greasemonkey


【解决方案1】:

@vamp 提出的在 jQuery 中删除标头的解决方案是正确的,但正如其他人所说,它仍然会导致发送一个空的 X-Requested-With 标头。

beforeSend 回调接收 jQuery 的 XHR 对象 (jqXHR),而不是实际的 XMLHttpRequest 对象 (xhr),它甚至在调用 beforeSend 之后才被实例化。

jqXHR 中的 setRequestHeader 方法将标头添加到对象中,然后在将 X-Requested-With 条目添加到标头对象之后使用同名的 xhr 方法进行迭代。

这是 jQuery 中发生这种情况的部分:

if ( !options.crossDomain && !headers["X-Requested-With"] ) {
    headers["X-Requested-With"] = "XMLHttpRequest";
}

for ( i in headers ) {
    xhr.setRequestHeader( i, headers[ i ] );
}

这会导致问题:如果您不指定 X-Requested-With 标头,那么 jQuery 将(除非 crossDomain 设置评估为 false,但这可能不是所需的解决方案)。然后它立即设置不能取消设置的 xhr 标头。


防止使用 jQuery.ajax 发送 X-Requested-With 标头:

jQuery.ajax 提供了一个设置 xhr,它覆盖了 jQuery 用于创建 XMLHttpRequest 对象的内置工厂方法。通过包装这个工厂方法,然后包装浏览器原生的 setRequestHeader 方法,可以忽略 jQuery 设置 X-Requested-With 标头的调用。

jQuery.ajax({

    url: yourAjaxUrl,

    // 'xhr' option overrides jQuery's default
    // factory for the XMLHttpRequest object.
    // Use either in global settings or individual call as shown here.
    xhr: function() {
        // Get new xhr object using default factory
        var xhr = jQuery.ajaxSettings.xhr();
        // Copy the browser's native setRequestHeader method
        var setRequestHeader = xhr.setRequestHeader;
        // Replace with a wrapper
        xhr.setRequestHeader = function(name, value) {
            // Ignore the X-Requested-With header
            if (name == 'X-Requested-With') return;
            // Otherwise call the native setRequestHeader method
            // Note: setRequestHeader requires its 'this' to be the xhr object,
            // which is what 'this' is here when executed.
            setRequestHeader.call(this, name, value);
        }
        // pass it on to jQuery
        return xhr;
    },

    success: function(data, textStatus, jqXHR) {
        // response from request without X-Requested-With header!
    }

    // etc...

});

【讨论】:

  • 我有一个发出跨域请求的脚本,本来应该是一个简单的CORS请求,但是由于jQuery自动添加了X-Requested-With标头,这被认为是自定义的,它使浏览器产生了一个不必要的 CORS 预检检查。感谢您分享此内容,我正在疯狂地试图弄清楚为什么我不能跳过预检。
【解决方案2】:

为什么不呢? 试试:

(function(){
    $.ajaxSettings.beforeSend=function(xhr){
        xhr.setRequestHeader('X-Requested-With', {toString: function(){ return ''; }});
    };
})(jQuery);

祝你好运!

【讨论】:

  • 并不是我真的期望它是特定于浏览器的,但它在 Firefox 4、Chrome 10、IE 9 和 Opera 11 中对我来说效果很好。对于我需要的东西,我不需要介意更改所有 AJAX请求,但我想知道是否有办法仅针对特定请求进行此操作。
  • 你不能给 $.ajax 调用本身添加一个 beforeSend 回调吗?
  • 根据@Marin 的[大部分相同] 的回答,看起来你可以。在sample jsFiddle 中,我删除了X-Requested-With 标头并且未能删除Referer 标头(Chrome 不会让它发生)。为了更有趣,我还整理了一个fiddle with this all-requests version
  • 不起作用。仅将标头的值设置为空字符串。标头仍在发送。
【解决方案3】:

要使用 jQuery 执行此操作,请将您的请求设置为跨域。示例:

server.php

<?='<pre>'.print_r($_SERVER,1);?>

client.js

$.ajax({ url: 'server.php', crossDomain: true }).success(function(r){document.write(r)})

【讨论】:

【解决方案4】:

“第二部分:你知道 Grease Monkey 的 ajax 请求是否设置了这个头吗?”

不,Greasemonkey's GM_xmlhttpRequest() 没有设置此标头(尽管您当然可以添加它)。

GM_xmlhttpRequest() 发出的默认请求看起来就像一个普通的浏览器请求。
例如:

GM_xmlhttpRequest
({
    method:     "GET",
    url:        "http://google.com/",
    onload:     function(response) {alert(response.responseText); }
});

在我的数据包嗅探器看来是这样的:

GET / HTTP/1.1
    Request Method: GET
    Request URI: /
    Request Version: HTTP/1.1
Host: google.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Keep-Alive: 115
Connection: keep-alive
Cookie: blah, blah, blah, blah, blah...

【讨论】:

    【解决方案5】:

    jQuery 目前没有公开执行此操作的方法,there was a ticket on it a while back 与 Firefox 错误相关,但他们没有将其作为选项,而是修复了 Firefox 中的错误问题。

    如果你很好奇,你可以在这里看到它的添加位置,但如果不编辑/覆盖 jQuery 核心就无法删除它:http://github.com/jquery/jquery/blob/master/src/ajax.js#L370

    【讨论】:

      【解决方案6】:

      你可以这样考虑:

      $.ajax({
        url: 'http://fiddle.jshell.net/favicon.png',
        beforeSend: function( xhr ) {
          xhr.setRequestHeader('X-Requested-With', {toString: function(){ return ''; }});
        },
        success: function( data ) {
          if (console && console.log){
            console.log( 'Got data without the X-Requested-With header' );
          }
        }
      });
      

      【讨论】:

      • 虽然beforeSend 部分是相同的,但这是一种更精细的删除标头的方法(每个请求与@vamp 所做的所有请求)。也就是说,可能应该澄清答案的不同之处,以帮助那些寻求此类解决方案的人。
      • 不起作用。仅将标头的值设置为空字符串。标头仍在发送。
      猜你喜欢
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2017-09-11
      • 2014-09-30
      相关资源
      最近更新 更多