From 84ac9babfc30bbea0707760b23dc85d7c0450082 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 26 Nov 2020 00:57:03 +0100 Subject: [PATCH] Use a local variable to prevent parallel requests being mixed up Fixes #3760 --- .../js/WoltLabSuite/Core/Ajax/Request.js | 18 ++++++++++-------- .../ts/WoltLabSuite/Core/Ajax/Request.ts | 19 +++++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js index 7d605c1fc4..c3e5bcaa12 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js @@ -106,8 +106,10 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis this._xhr.withCredentials = true; } const options = Core.clone(this._options); - this._xhr.onload = () => { - const xhr = this._xhr; + // Use a local variable in all callbacks, because `this._xhr` can be overwritten by + // subsequent requests while a request is still in-flight. + const xhr = this._xhr; + xhr.onload = () => { if (xhr.readyState === XMLHttpRequest.DONE) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { if (options.responseType && xhr.getResponseHeader("Content-Type").indexOf(options.responseType) !== 0) { @@ -123,24 +125,24 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis } } }; - this._xhr.onerror = () => { - this._failure(this._xhr, options); + xhr.onerror = () => { + this._failure(xhr, options); }; if (this._options.progress) { - this._xhr.onprogress = this._options.progress; + xhr.onprogress = this._options.progress; } if (this._options.uploadProgress) { - this._xhr.upload.onprogress = this._options.uploadProgress; + xhr.upload.onprogress = this._options.uploadProgress; } if (this._options.type === "POST") { let data = this._options.data; if (typeof data === "object" && Core.getType(data) !== "FormData") { data = Core.serialize(data); } - this._xhr.send(data); + xhr.send(data); } else { - this._xhr.send(); + xhr.send(); } } /** diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts index 23dd37458e..71fc024db4 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts @@ -150,8 +150,11 @@ class AjaxRequest { } const options = Core.clone(this._options) as RequestOptions; - this._xhr.onload = () => { - const xhr = this._xhr!; + + // Use a local variable in all callbacks, because `this._xhr` can be overwritten by + // subsequent requests while a request is still in-flight. + const xhr = this._xhr; + xhr.onload = () => { if (xhr.readyState === XMLHttpRequest.DONE) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { if (options.responseType && xhr.getResponseHeader("Content-Type")!.indexOf(options.responseType) !== 0) { @@ -165,15 +168,15 @@ class AjaxRequest { } } }; - this._xhr.onerror = () => { - this._failure(this._xhr!, options); + xhr.onerror = () => { + this._failure(xhr, options); }; if (this._options.progress) { - this._xhr.onprogress = this._options.progress; + xhr.onprogress = this._options.progress; } if (this._options.uploadProgress) { - this._xhr.upload.onprogress = this._options.uploadProgress; + xhr.upload.onprogress = this._options.uploadProgress; } if (this._options.type === "POST") { @@ -182,9 +185,9 @@ class AjaxRequest { data = Core.serialize(data); } - this._xhr.send(data as any); + xhr.send(data as any); } else { - this._xhr.send(); + xhr.send(); } } -- 2.20.1