重用XMLHttpRequest对象或创建一个新对象

Reuse XMLHttpRequest object or create a new one?

本文关键字:对象 一个 新对象 XMLHttpRequest 创建 重用      更新时间:2023-09-26

我搜索了stackoverflow,但得到了矛盾的答案:

为什么要重用XmlHttpRequest对象?

Ajax密集型页面:重用相同的XMLHttpRequest对象还是每次都创建一个新对象?

此外,w3schools.com上还有一条建议:

如果你的网站上有多个AJAX任务,你应该创建一个用于创建XMLHttpRequest对象的标准函数,并调用这适用于每个AJAX任务。

为什么要推荐?相反,我在页面上使用全局XMLHttpRequest对象来处理所有Ajax任务。

您误解了W3School的建议。我将重点介绍相关部分:

如果您的网站上有多个AJAX任务,则应创建one标准函数来创建XMLHttpRequest对象,并为每个AJAX任务调用此函数。

它说您使用一个AJAX函数来获取请求。此功能将处理IE和其他浏览器之间的不一致。标准兼容浏览器中的XMLHttpRequest和IE中的ActiveXObject

我建议使用多个XHR对象。对于一个全局xhr对象,应用程序在给定时间只能处理一个请求。它也容易出错(例如XMLHttpRequest多次启动而没有启动onreadystatechange函数)。

W3schools的意思是:

function createXHR() {
    try {
        return new XMLHttpRequest();
    } catch (e) {
        try {
            return new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
            return new ActiveXObject("Msxml2.XMLHTTP");
        }
    }
}
var xhr = createXHR();
xhr.open('get', '/test', true);
xhr.send();

尽管最好创建一个处理请求的函数,例如jQuery.ajax

最好为您正在制作的每个XHR使用不同的对象。即使有办法做到这一点,也要避免!为每个请求创建新对象没有问题。如果你担心内存泄漏或类似的事情,不要担心,它们都是正确的GC。


如果您的网站上有多个AJAX任务,则应该创建一个标准函数来创建XMLHttpRequest对象,并为每个AJAX任务调用此函数。

实际上,这意味着你有一个函数可以创建一个新对象,并在每次调用时返回它

function newXHR(){
    return a new instance of XHR();
}

您强调的建议是,您应该有一个处理AJAX的FUNCTION,而不是专门的一个XMLHTTPRequest对象。

每个问题我都会用不同的答案。

反对这一点的常见论点涉及建立XHR所涉及的间接费用。然而,这在任何使用AJAX的网站中都是可以忽略不计的(即,不是作为web套接字的劳动替代品),而且在任何情况下,重新使用XHR都会产生很多相同的开销。你仍然需要打开连接,启动它,连接监听器等。

浏览器在给定时间允许多少连接网关方面各不相同,因此由浏览器来控制XHR可以做什么。换句话说,你不必担心管理这方面的问题。

最后,如果XHR是可删除的(对象的属性而不是变量),那么在使用完它们之后,没有什么可以阻止您手动删除它们。

来自MDN Web文档:

如果httpRequest变量被全局使用,那么竞争函数调用makeRequest()可能会相互覆盖,从而导致竞争条件将httpRequest变量声明为闭包的本地变量包含AJAX函数可以避免这种情况。

来源:https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started

我使用的是类似的模式

var xhrSendBuffer = new Object();
function sendData(url, model) {
    if (!xhrSendBuffer[url]) {
        let xhr = new XMLHttpRequest();
        xhr.onloadend = xhrDone;
        xhr.error=xhrError;
        xhr.onabort = xhrAbborted;
        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
        xhrSendBuffer[url] = xhr;
    }
    xhrSendBuffer[url].send(JSON.stringify(model));
}
function xhrDone(e) {
    console.log(e);
}
function xhrError(e) {
    console.error(e);
}
function xhrAbborted(e) {
console.warn(e);
}

如果我最终在自己的网站上生成DOS,因为我向同一个url发送了多个请求,我可以在发送下一个请求之前使用xhr.readyState来查看它有多忙,但我还没有遇到这个问题。