From 8601680f73b338a4bcf29bd9dfa99fa84786b083 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 16 Aug 2023 19:40:51 +0900 Subject: [PATCH 1/5] avoid memory leakage and circular reference --- src/xhr-proxy.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/xhr-proxy.js b/src/xhr-proxy.js index 73f7d76..7ee4f0c 100644 --- a/src/xhr-proxy.js +++ b/src/xhr-proxy.js @@ -175,11 +175,29 @@ function proxyAjax(proxy, win) { config.async = args[2]; config.user = args[3]; config.password = args[4]; - config.xhr = xhr; + Object.defineProperty(config, 'xhr', { + get() { + return xhr; // xhr wil be set to null after xhr.readyState === XMLHttpRequest.DONE + }, + set() { + // READONLY + }, + enumerable: false, + configurable: true + }); + // config.xhr = xhr; var evName = 'on' + eventReadyStateChange; if (!xhr[evName]) { xhr[evName] = function () { - return stateChangeCallback(xhr, _this); + if (config.xhr === this) { + var result = stateChangeCallback(this, _this); + if (this.readyState === XMLHttpRequest.DONE) { + xhr = null; // avoid memory leak + delete config.xhr; + xhr[evName] = null; + } + return result; + } }; } From a5ed639735b22e51c54b35e8b6b4035d691e69dc Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 16 Aug 2023 20:19:15 +0900 Subject: [PATCH 2/5] moved "avoid memory leakage code" to `stateChangeCallback` --- src/xhr-proxy.js | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/xhr-proxy.js b/src/xhr-proxy.js index 7ee4f0c..ebd2293 100644 --- a/src/xhr-proxy.js +++ b/src/xhr-proxy.js @@ -149,10 +149,17 @@ function proxyAjax(proxy, win) { } function stateChangeCallback(xhr, xhrProxy) { - if (xhr.readyState === 4 && xhr.status !== 0) { - handleResponse(xhr, xhrProxy); - } else if (xhr.readyState !== 4) { - triggerListener(xhr, eventReadyStateChange); + var config = xhrProxy ? xhrProxy.config : null; + if (config && xhr && config.xhr === xhr) { + if (xhr.readyState === 4 && xhr.status !== 0) { + handleResponse(xhr, xhrProxy); + } else if (xhr.readyState !== 4) { + triggerListener(xhr, eventReadyStateChange); + } + if (xhr.readyState === XMLHttpRequest.DONE) { + config.xhr = null; + xhr['on' + eventReadyStateChange] = null; + } } return true; } @@ -179,8 +186,8 @@ function proxyAjax(proxy, win) { get() { return xhr; // xhr wil be set to null after xhr.readyState === XMLHttpRequest.DONE }, - set() { - // READONLY + set(nv) { + if (nv === null) xhr = null; }, enumerable: false, configurable: true @@ -189,15 +196,7 @@ function proxyAjax(proxy, win) { var evName = 'on' + eventReadyStateChange; if (!xhr[evName]) { xhr[evName] = function () { - if (config.xhr === this) { - var result = stateChangeCallback(this, _this); - if (this.readyState === XMLHttpRequest.DONE) { - xhr = null; // avoid memory leak - delete config.xhr; - xhr[evName] = null; - } - return result; - } + return stateChangeCallback(this, _this); }; } From 3917284deede49222b207610c0c5032ee138a511 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 16 Aug 2023 21:07:44 +0900 Subject: [PATCH 3/5] fix: missing return value in setter --- src/xhr-proxy.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xhr-proxy.js b/src/xhr-proxy.js index ebd2293..4a758da 100644 --- a/src/xhr-proxy.js +++ b/src/xhr-proxy.js @@ -188,6 +188,7 @@ function proxyAjax(proxy, win) { }, set(nv) { if (nv === null) xhr = null; + return true; }, enumerable: false, configurable: true From 712d00d00ca1613829d264a450812ef18a8271e9 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 16 Aug 2023 21:28:32 +0900 Subject: [PATCH 4/5] moved "avoid memory leakage code" to `handler.resolve` and `handler.reject` --- src/xhr-proxy.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/xhr-proxy.js b/src/xhr-proxy.js index 4a758da..cf9c828 100644 --- a/src/xhr-proxy.js +++ b/src/xhr-proxy.js @@ -64,11 +64,22 @@ Handler[prototype] = Object.create({ triggerListener(xhr, eventReadyStateChange); triggerListener(xhr, eventLoad); triggerListener(xhr, eventLoadEnd); + if (xhr.readyState === 4) { + if (xhr.config) xhr.config.xhr = null; + xhr['on' + eventReadyStateChange] = null; + xhr.config = null; + } }, reject: function reject(error) { + var xhr = this.xhr; this.xhrProxy.status = 0; - triggerListener(this.xhr, error.type); - triggerListener(this.xhr, eventLoadEnd); + triggerListener(xhr, error.type); + triggerListener(xhr, eventLoadEnd); + if (xhr.readyState === 4) { + if (xhr.config) xhr.config.xhr = null; + xhr['on' + eventReadyStateChange] = null; + xhr.config = null; + } } }); @@ -156,10 +167,6 @@ function proxyAjax(proxy, win) { } else if (xhr.readyState !== 4) { triggerListener(xhr, eventReadyStateChange); } - if (xhr.readyState === XMLHttpRequest.DONE) { - config.xhr = null; - xhr['on' + eventReadyStateChange] = null; - } } return true; } @@ -184,7 +191,7 @@ function proxyAjax(proxy, win) { config.password = args[4]; Object.defineProperty(config, 'xhr', { get() { - return xhr; // xhr wil be set to null after xhr.readyState === XMLHttpRequest.DONE + return xhr; // xhr wil be set to null after xhr.readyState === XMLHttpRequest.DONE (4) }, set(nv) { if (nv === null) xhr = null; From 4c5a4d0b1903705f5ed6f2a0598c173920625abc Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Thu, 17 Aug 2023 00:36:49 +0900 Subject: [PATCH 5/5] code typo --- src/xhr-proxy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xhr-proxy.js b/src/xhr-proxy.js index cf9c828..38b3573 100644 --- a/src/xhr-proxy.js +++ b/src/xhr-proxy.js @@ -160,7 +160,7 @@ function proxyAjax(proxy, win) { } function stateChangeCallback(xhr, xhrProxy) { - var config = xhrProxy ? xhrProxy.config : null; + var config = xhr ? xhr.config : null; if (config && xhr && config.xhr === xhr) { if (xhr.readyState === 4 && xhr.status !== 0) { handleResponse(xhr, xhrProxy);