30

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

为什么要重用 XmlHttpRequest 对象?

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

另外,在 w3schools.com 上有一个建议:

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

为什么这个建议?相反,我在我的页面上使用全局 XMLHttpRequest 对象来处理所有 Ajax 任务。

4

5 回答 5

15

您误解了 W3School 的建议。我将突出显示相关部分:

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

它说您使用一个 AJAX 函数来获取请求。这个函数会处理IE和其他浏览器的不一致。XMLHttpRequest在符合标准的浏览器和ActiveXObjectIE 中。

我建议使用多个 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.

于 2012-07-16T10:25:54.653 回答
8

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


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

这实际上意味着您有一个函数可以创建一个新对象并在每次调用它时返回它。它类似于:

function newXHR(){
    return a new instance of XHR();
}
于 2012-07-16T10:25:25.900 回答
2

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

我会为每个问题使用不同的问题。

反对这一点的常见论点涉及建立 XHR 所涉及的开销。然而,这在任何使用 AJAX 的站点中几乎可以忽略不计(即不是作为 Web 套接字的劳动替代品),并且在任何情况下,大部分相同的开销都将适用于重新使用 XHR。您仍然必须打开连接、触发它、附加侦听器等。

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

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

于 2012-07-16T10:29:59.770 回答
0

来自 MDN 网络文档:

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

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

于 2020-01-20T06:12:27.513 回答
0

我正在使用这样的模式

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 在发送下一个请求之前查看它有多忙,但是我还没有遇到这个问题。

于 2020-03-05T09:50:16.827 回答