jQuery:在完整函数内访问二进制 AJAX 响应还是在回调函数外访问 XHR 对象? [英] jQuery: access binary AJAX response inside complete function or access XHR object outside of callback functions?

查看:14
本文介绍了jQuery:在完整函数内访问二进制 AJAX 响应还是在回调函数外访问 XHR 对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 jQuery 处理二进制 AJAX 响应有很多问题,例如 this这个这个.没有帮助.

There are many questions on handling binary AJAX responses with jQuery like this, this, and this. None help.

目标:(1)动态判断响应是否包含二进制数据,并以不同于文本的方式处理;(2) 分析响应头;和 (3) 从一个函数中同时完成.

Goals: (1) dynamically determine if a response contains binary data, and handle it differently from text; (2) analyze response headers; and (3) do both from a single function.

理想情况下,这可以通过 complete 函数完成,但 complete 函数无法访问 XHR 对象.jqXHR 应该是 XHR 对象的超集,但 XHR.response 为空.

Ideally, this can be done from the complete function, but the complete function doesn't have access to the XHR object. jqXHR is supposed to be a superset of the XHR object, but XHR.response is blank.

$.ajax(settings) 的返回值包含二进制数据,但 XHR 对象不再可用——因此似乎无法分析响应头.

The return value of $.ajax(settings) contains the binary data, but the XHR object is no longer available -- so it seems not possible to analyze the response headers.

是否可以在 complete 回调内访问二进制 AJAX 响应或在回调函数外访问 XHR 对象?

Is it possible to access the binary AJAX response inside the complete callback or access the XHR object outside of the callback functions? The

// Assume @data contains body and URL values.

let settings = {
    url: data.url,
    method: "post",
    timeout: 0,
    contentType: false,
    processData: false,
    data: data.body,
    xhr: function() {
                // Create XMLHttpRequest object.
                let xhr = new XMLHttpRequest();

                // Handle event for when response headers arrive.
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 2) {
                        if (xhr.status == 200) {
                            xhr.responseType = 'blob';
                        } else {
                            xhr.responseType = 'text';
                        }
                    }
                };

                return xhr;
    },
    complete: function(xhr, status, error) {
        // Can access response headers but not binary response here.
    }
};

let response = await $.ajax(settings);
// @response is blob but cannot access XHR object here.

推荐答案

我不知道您是否受到某些过时 jQuery 版本的限制,但实际上您可以做到所有这些.

I don't know if you are constrained by some archaic version of jQuery, but you can actually do all of that.

$.ajax(settings) 的返回值包含二进制数据,但 XHR 对象不再可用——因此似乎无法分析响应头.

The return value of $.ajax(settings) contains the binary data, but the XHR object is no longer available -- so it seems not possible to analyze the response headers.

技术上,没有.$.ajax(settings) 的返回值 是 jqXHR 对象,因此您可以访问在回调中获得的相同对象.在您的代码中,您使用的是 async/await 模式,因此无法访问 jqXHR 对象.但是你可以这样做

Technically, no. The return value of $.ajax(settings) is jqXHR object, So you can access the same object that you get within the callbacks. In your code, you are using the async/await pattern, and thus not able to access the jqXHR object. But you can do so

let jqXHR = $.ajax(settings);
jqXHR.then((response) => {
    console.log(response);
    console.log(res.getAllResponseHeaders());
});

这样,您将同时获得 jqXHR 对象和响应对象.

This way, you will get both the jqXHR object and the response object.

理想情况下,这可以从完整函数中完成,但完整函数无权访问 XHR 对象.jqXHR 应该是 XHR 对象的超集,但 XHR.response 为空.

Ideally, this can be done from the complete function, but the complete function doesn't have access to the XHR object. jqXHR is supposed to be a superset of the XHR object, but XHR.response is blank.

因为您在错误的时间访问它.为了填充 response 属性,您必须等到 readyState 4 而不是 2.请参阅 XHR readyState.
然后,您也可以在完整回调中获取响应对象.只需像处理 $.ajax(settings) 响应一样处理 xhr 回调参数即可.

Because you are accessing it at the wrong time. In order for the response property to be populated, you have to wait until readyState 4 instead of 2. Refer to XHR readyState.
Then again, you can get the response object within the complete callback too. Just treat the xhr callback parameter the same way you would do the $.ajax(settings) response.

complete: function(xhr, status, error) {
    res.then((response) => {
        console.log(response);
        console.log(res.getAllResponseHeaders());
    });
}

如果您使用的是较新版本的 jQuery(我猜是过去 2-3 年的),您甚至可以编写这段简洁的代码

If you are using the newer versions of jQuery (I guess the last 2-3 year ones), you can even write this neat code

complete: async function (xhr, status, error) {
    console.log(xhr.getAllResponseHeaders());
    console.log(await xhr);
}

如果您字面上需要 XHR 对象,您也可以进行此 hack.

And if you literally need the XHR object, you can do this hack too.

let xhr;
let settings = {
    //rest of things
    xhr: function () {
        return xhr = new XMLHttpRequest();
    }
};
let jqXHR = $.ajax(settings);
xhr.onreadystatechange = function() {
    if (xhr.readyState == 2) {
        if (xhr.status == 200) {
            xhr.responseType = 'blob';
        } else {
            xhr.responseType = 'text';
        }
    }
};
let response = await jqXHR;
console.log(response);

这篇关于jQuery:在完整函数内访问二进制 AJAX 响应还是在回调函数外访问 XHR 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆