XMLHttpRequest未添加头文件 - "X-Requested-With: XMLHttpRequest"

17
我有一个 ajax 调用,之前我使用 jQuery.ajax() 向 MVC action 发送请求,一切都正常。但是由于某些表单具有文件控件,因此我将它从使用 jQuery.ajax() 更改为使用 XMLHttpRequest,并使用 HTML5 File API 发送请求。
自从进行了这个更改后,MVC action 方法不再将其视为 ajax 请求。通过使用 Fiddler2,我注意到它不再将 "X-Requested-With: XMLHttpRequest" 添加到请求中,我认为这就是问题所在。
我试图保持方法的通用性以处理两种情况(有/无文件输入),但我尝试发送的表单中没有文件输入,只有普通文本框等。以下是我用于发送 ajax 请求的代码:
// get the edit tender form
var $Form = $Button.closest('form');
var Url = $Form.attr('action');
var AjaxRequestObject = new XMLHttpRequest();
var FormDataToSend = new FormData();

$Form.find(':input').each(function () {
    if ($(this).is('input[type="file"]')) {
        var files = $(this)[0].files;
        if (files.length > 0) {
            FormDataToSend.append(this.name, files[0]);
        }
    } else {
        FormDataToSend.append(this.name, $(this).val());
    }
});

AjaxRequestObject.open('POST', Url, true);
AjaxRequestObject.onreadystatechange = function () {
    if (AjaxRequestObject.readyState == 4) {
        // handle response.
        if (AjaxRequestObject.status == 200) {
            if (!AjaxErrorExists(AjaxRequestObject.responseText, )) {
                alert("success");
                console.log(AjaxRequestObject.responseText);
            }
            else {
                alert('failure');
            }
        }
        else {
            alert('failure');
        }
    }
};

AjaxRequestObject.send(FormDataToSend);

这段代码是在我遇到问题后由Darin Dimitrov提供解决方案,并让我能够通过ajax发送文件输入的。

你有什么想法,为什么这个请求不会为ajax调用发送头信息?

3个回答

23

X-Requested-With 是由 jQuery 自动添加的。您可以使用 AjaxRequestObject.setRequestHeader() 方便地自己添加它。详情请参见文档


注:X-Requested-With 是一个 HTTP 头,用于指示请求是由 Ajax 发起的。

3
太棒了,我不知道这一点。在发送请求之前,我添加了以下内容:"AjaxRequestObject.setRequestHeader('X-Requested-With','XMLHttpRequest');",我认为它已经生效了。 - eyeballpaul

13

我在检测我的请求是否为ajax方面遇到了麻烦。也许这个示例可以帮助某人节省一两分钟:

var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', URL, true);  // `true` for async call, `false` for sync.

// The header must be after `.open()`, but before `.send()`
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

xmlhttp.onreadystatechange = function() {
    // 4th state is the last:
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { ... }
};
xmlhttp.send();

使用Flask进行测试。


为什么我执行相同的操作时,Flask请求中的request.is_xhr属性为False? - Sargsyan Grigor

0

您可以覆盖所有原生的XMLHttpRequest.open方法调用,并在其中添加X-Requested-With头,例如:

(function () {  

    // @author https://github.com/stopsopa jfdsa78y453cq5hjfd7s877834h4h3

    if (window.XMLHttpRequest.prototype.onOpen)  {
        return console.log('XMLHttpRequest.onOpen is already defined');
    }

    function over(method, on, off) {

        var old = window.XMLHttpRequest.prototype[method];

        if (!old.old) {

            var stack = [];

            window.XMLHttpRequest.prototype[on] = function (fn) {
                if (typeof fn === 'function') {
                    stack.push(fn);
                }
            }

            window.XMLHttpRequest.prototype[off] = function (fn) {
                for (var i = 0, l = stack.length ; i < l ; i += 1 ) {
                    if (stack[i] === fn) {
                        stack.splice(i, 1);
                        break;
                    }
                }
            }

            window.XMLHttpRequest.prototype[method] = function () {
                var args = Array.prototype.slice.call(arguments);

                var ret = old.apply(this, args);

                for (var i = 0, l = stack.length ; i < l ; i += 1 ) {
                    stack[i].apply(this, args);
                }

                return ret;
            }

            window.XMLHttpRequest.prototype[method].old = old;
        }
    }

    over('open', 'onOpen', 'offOpen')

    XMLHttpRequest.prototype.onOpen(function () {
        this.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    });
}());

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