могу ли я удалить заголовок X-Requested-With из запросов ajax?


Я хотел бы знать, был ли у кого-нибудь опыт в попытке удалить заголовок 'X-Requested-With' из запроса ajax, сделанного jquery (или plain JS). возможно ли это?

2-я часть: вы знаете, если ajax-запросы Grease Monkey устанавливают этот заголовок?

Спасибо

Заголовок

Выглядит так:

X-Requested-With XMLHttpRequest
6 22

6 ответов:

" 2-я часть: вы знаете, если ajax-запросы Grease Monkey устанавливают этот заголовок?"

Нет, Greasemonkey 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...

Решение для удаления заголовка в jQuery, предложенное @vamp, находится на правильном пути, но, как заявили другие, оно все равно приведет к отправке пустого заголовка X-Requested-With.

Обратный вызов beforeSend получает объектjQuery XHR (jqXHR), а не фактический объект XMLHttpRequest (xhr), который даже не создается до вызова beforeSend.

Метод setRequestHeader в jqXHR добавляет заголовки к объекту, который затем повторяется позже используя метод xhr с тем же именем, сразу после добавления записи X-Requested-With в объект headers.

Вот часть в 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,которые не могут быть отменены.


Чтобы предотвратить отправку X-Requested-With header с jQuery.ajax:

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...

});

Почему бы и нет? попробуйте:

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

Удачи!

Чтобы сделать это с помощью jQuery, задайте запрос как междоменный. Пример:

Сервер.php

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

Клиент.js

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

JQuery не предоставляет метод для этого на данный момент, некоторое время назад на нем был тикет, связанный с ошибками Firefox, но вместо того, чтобы сделать его опцией, они исправили ошибку в Firefox.

Если вам интересно, вы можете посмотреть, где он добавлен здесь, но вы не можете удалить его без редактирования / переопределения ядра jQuery: http://github.com/jquery/jquery/blob/master/src/ajax.js#L370

Вы можете рассмотреть следующее:

$.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' );
    }
  }
});