diff --git a/src/webui/www/private/addpeers.html b/src/webui/www/private/addpeers.html
index 5ef01c2a4f0b..ad645b3d9e63 100644
--- a/src/webui/www/private/addpeers.html
+++ b/src/webui/www/private/addpeers.html
@@ -22,8 +22,8 @@
                 }
             });
 
-            const hash = new URI().getData("hash");
-            if (!hash)
+            const hash = new URLSearchParams(window.location.search).get("hash");
+            if (hash === null)
                 return;
 
             $("peers").focus();
diff --git a/src/webui/www/private/addtrackers.html b/src/webui/www/private/addtrackers.html
index df84f1443998..818f20f09bcd 100644
--- a/src/webui/www/private/addtrackers.html
+++ b/src/webui/www/private/addtrackers.html
@@ -30,7 +30,7 @@
                 fetch("api/v2/torrents/addTrackers", {
                         method: "POST",
                         body: new URLSearchParams({
-                            hash: new URI().getData("hash"),
+                            hash: new URLSearchParams(window.location.search).get("hash"),
                             urls: $("trackersUrls").value
                         })
                     })
diff --git a/src/webui/www/private/addwebseeds.html b/src/webui/www/private/addwebseeds.html
index c03f7687bf92..c87c171467f9 100644
--- a/src/webui/www/private/addwebseeds.html
+++ b/src/webui/www/private/addwebseeds.html
@@ -29,7 +29,7 @@
                 fetch("api/v2/torrents/addWebSeeds", {
                         method: "POST",
                         body: new URLSearchParams({
-                            hash: new URI().getData("hash"),
+                            hash: new URLSearchParams(window.location.search).get("hash"),
                             urls: $("urls").value.split("\n").map(w => encodeURIComponent(w.trim())).filter(w => (w.length > 0)).join("|")
                         })
                     })
diff --git a/src/webui/www/private/confirmfeeddeletion.html b/src/webui/www/private/confirmfeeddeletion.html
index bfd19d661a94..b0f2abe5c6e5 100644
--- a/src/webui/www/private/confirmfeeddeletion.html
+++ b/src/webui/www/private/confirmfeeddeletion.html
@@ -13,7 +13,6 @@
         "use strict";
 
         window.addEventListener("DOMContentLoaded", () => {
-            const paths = new URI().getData("paths").split("|");
             $("cancelBtn").focus();
             $("cancelBtn").addEventListener("click", (e) => {
                 e.preventDefault();
@@ -25,7 +24,8 @@
                 e.stopPropagation();
 
                 let completionCount = 0;
-                paths.forEach((path) => {
+                const paths = new URLSearchParams(window.location.search).get("paths").split("|");
+                for (const path of paths) {
                     fetch("api/v2/rss/removeItem", {
                             method: "POST",
                             body: new URLSearchParams({
@@ -42,7 +42,7 @@
                                 window.parent.qBittorrent.Client.closeFrameWindow(window);
                             }
                         });
-                });
+                }
             });
         });
     </script>
diff --git a/src/webui/www/private/confirmruleclear.html b/src/webui/www/private/confirmruleclear.html
index 8b562b2573e5..9817d3c1d25e 100644
--- a/src/webui/www/private/confirmruleclear.html
+++ b/src/webui/www/private/confirmruleclear.html
@@ -13,8 +13,6 @@
         "use strict";
 
         window.addEventListener("DOMContentLoaded", () => {
-            const rules = new URI().getData("rules").split("|");
-
             $("cancelBtn").focus();
             $("cancelBtn").addEventListener("click", (e) => {
                 e.preventDefault();
@@ -26,7 +24,8 @@
                 e.stopPropagation();
 
                 let completionCount = 0;
-                rules.forEach((rule) => {
+                const rules = new URLSearchParams(window.location.search).get("rules").split("|");
+                for (const rule of rules) {
                     window.parent.qBittorrent.RssDownloader.modifyRuleState(decodeURIComponent(rule), "previouslyMatchedEpisodes", [], () => {
                         ++completionCount;
                         if (completionCount === rules.length) {
@@ -34,7 +33,7 @@
                             window.parent.qBittorrent.Client.closeFrameWindow(window);
                         }
                     });
-                });
+                }
             });
         });
     </script>
diff --git a/src/webui/www/private/confirmruledeletion.html b/src/webui/www/private/confirmruledeletion.html
index b47608f00fb4..cf9f7d874916 100644
--- a/src/webui/www/private/confirmruledeletion.html
+++ b/src/webui/www/private/confirmruledeletion.html
@@ -13,8 +13,6 @@
         "use strict";
 
         window.addEventListener("DOMContentLoaded", () => {
-            const rules = new URI().getData("rules").split("|");
-
             $("cancelBtn").focus();
             $("cancelBtn").addEventListener("click", (e) => {
                 e.preventDefault();
@@ -26,7 +24,8 @@
                 e.stopPropagation();
 
                 let completionCount = 0;
-                rules.forEach((rule) => {
+                const rules = new URLSearchParams(window.location.search).get("rules").split("|");
+                for (const rule of rules) {
                     fetch("api/v2/rss/removeRule", {
                             method: "POST",
                             body: new URLSearchParams({
@@ -43,7 +42,7 @@
                                 window.parent.qBittorrent.Client.closeFrameWindow(window);
                             }
                         });
-                });
+                }
             });
         });
     </script>
diff --git a/src/webui/www/private/confirmtrackerdeletion.html b/src/webui/www/private/confirmtrackerdeletion.html
index ecf51b3f5e88..4324f528f51f 100644
--- a/src/webui/www/private/confirmtrackerdeletion.html
+++ b/src/webui/www/private/confirmtrackerdeletion.html
@@ -13,9 +13,10 @@
         "use strict";
 
         window.addEventListener("DOMContentLoaded", () => {
-            const host = new URI().getData("host");
-            const urls = new URI().getData("urls");
-            $("confirmDeleteTrackerText").textContent = "QBT_TR(Are you sure you want to remove tracker %1 from all torrents?)QBT_TR[CONTEXT=TrackersFilterWidget]".replace("%1", `"${host}"`);
+            const searchParams = new URLSearchParams(window.location.search);
+            const host = searchParams.get("host");
+
+            $("confirmDeleteTrackerText").textContent = "QBT_TR(Are you sure you want to remove tracker %1 from all torrents?)QBT_TR[CONTEXT=TrackersFilterWidget]".replace("%1", host);
 
             $("cancelBtn").focus();
             $("cancelBtn").addEventListener("click", (e) => {
@@ -29,7 +30,7 @@
                         method: "POST",
                         body: new URLSearchParams({
                             hash: "*",
-                            urls: urls
+                            urls: searchParams.get("urls")
                         })
                     })
                     .then((response) => {
diff --git a/src/webui/www/private/download.html b/src/webui/www/private/download.html
index 5f481a735f74..ecd1bb6bbb28 100644
--- a/src/webui/www/private/download.html
+++ b/src/webui/www/private/download.html
@@ -163,13 +163,10 @@ <h2><label for="urls">QBT_TR(Add torrent links)QBT_TR[CONTEXT=AddNewTorrentDialo
     <script>
         "use strict";
 
-        const encodedUrls = new URI().getData("urls");
-        if (encodedUrls) {
-            const urls = encodedUrls.split("|").map((url) => {
-                return decodeURIComponent(url);
-            });
-
-            if (urls.length)
+        const encodedUrls = new URLSearchParams(window.location.search).get("urls");
+        if (encodedUrls !== null) {
+            const urls = encodedUrls.split("|").map(decodeURIComponent);
+            if (urls.length > 0)
                 $("urls").value = urls.join("\n");
         }
 
diff --git a/src/webui/www/private/downloadlimit.html b/src/webui/www/private/downloadlimit.html
index f9ee2cd251ad..d703cf79ebf0 100644
--- a/src/webui/www/private/downloadlimit.html
+++ b/src/webui/www/private/downloadlimit.html
@@ -46,7 +46,7 @@
             }
         });
 
-        const hashes = new URI().getData("hashes").split("|");
+        const hashes = new URLSearchParams(window.location.search).get("hashes").split("|");
         const setDlLimit = () => {
             const limit = Number($("dllimitUpdatevalue").value) * 1024;
             if (hashes[0] === "global") {
diff --git a/src/webui/www/private/editfeedurl.html b/src/webui/www/private/editfeedurl.html
index 83ffbd9d0e31..83618a0b53cb 100644
--- a/src/webui/www/private/editfeedurl.html
+++ b/src/webui/www/private/editfeedurl.html
@@ -27,7 +27,8 @@
                 }
             });
 
-            const currentUrl = new URI().getData("url");
+            const searchParams = new URLSearchParams(window.location.search);
+            const currentUrl = searchParams.get("url");
 
             $("url").value = currentUrl;
             $("url").focus();
@@ -54,7 +55,7 @@
                 fetch("api/v2/rss/setFeedURL", {
                         method: "POST",
                         body: new URLSearchParams({
-                            path: new URI().getData("path"),
+                            path: searchParams.get("path"),
                             url: newUrl
                         })
                     })
diff --git a/src/webui/www/private/edittracker.html b/src/webui/www/private/edittracker.html
index 0d68c0b5da33..2b4ff2553ef8 100644
--- a/src/webui/www/private/edittracker.html
+++ b/src/webui/www/private/edittracker.html
@@ -26,8 +26,9 @@
                 }
             });
 
-            const currentUrl = new URI().getData("url");
-            if (!currentUrl)
+            const searchParams = new URLSearchParams(window.location.search);
+            const currentUrl = searchParams.get("url");
+            if (currentUrl === null)
                 return;
 
             $("trackerUrl").value = currentUrl;
@@ -40,7 +41,7 @@
                 fetch("api/v2/torrents/editTracker", {
                         method: "POST",
                         body: new URLSearchParams({
-                            hash: new URI().getData("hash"),
+                            hash: searchParams.get("hash"),
                             origUrl: currentUrl,
                             newUrl: $("trackerUrl").value
                         })
diff --git a/src/webui/www/private/editwebseed.html b/src/webui/www/private/editwebseed.html
index 853fe1179828..ef6b70998abf 100644
--- a/src/webui/www/private/editwebseed.html
+++ b/src/webui/www/private/editwebseed.html
@@ -26,7 +26,8 @@
                 }
             });
 
-            const origUrl = new URI().getData("url");
+            const searchParams = new URLSearchParams(window.location.search);
+            const origUrl = searchParams.get("url");
             $("url").value = decodeURIComponent(origUrl);
             $("url").focus();
 
@@ -36,7 +37,7 @@
                 fetch("api/v2/torrents/editWebSeed", {
                         method: "POST",
                         body: new URLSearchParams({
-                            hash: new URI().getData("hash"),
+                            hash: searchParams.get("hash"),
                             origUrl: origUrl,
                             newUrl: encodeURIComponent($("url").value.trim())
                         })
diff --git a/src/webui/www/private/newcategory.html b/src/webui/www/private/newcategory.html
index 4b6d9b859990..116e12bfcfd7 100644
--- a/src/webui/www/private/newcategory.html
+++ b/src/webui/www/private/newcategory.html
@@ -28,10 +28,11 @@
                 }
             });
 
-            const uriAction = window.qBittorrent.Misc.safeTrim(new URI().getData("action"));
-            const uriHashes = window.qBittorrent.Misc.safeTrim(new URI().getData("hashes"));
-            const uriCategoryName = window.qBittorrent.Misc.safeTrim(new URI().getData("categoryName"));
-            const uriSavePath = window.qBittorrent.Misc.safeTrim(new URI().getData("savePath"));
+            const searchParams = new URLSearchParams(window.location.search);
+            const uriAction = window.qBittorrent.Misc.safeTrim(searchParams.get("action"));
+            const uriHashes = window.qBittorrent.Misc.safeTrim(searchParams.get("hashes"));
+            const uriCategoryName = window.qBittorrent.Misc.safeTrim(searchParams.get("categoryName"));
+            const uriSavePath = window.qBittorrent.Misc.safeTrim(searchParams.get("savePath"));
 
             if (uriAction === "edit") {
                 if (!uriCategoryName)
diff --git a/src/webui/www/private/newfeed.html b/src/webui/www/private/newfeed.html
index 2353396fc841..b3815a63ee39 100644
--- a/src/webui/www/private/newfeed.html
+++ b/src/webui/www/private/newfeed.html
@@ -28,7 +28,6 @@
             });
 
             $("feedURL").focus();
-            const path = new URI().getData("path");
             $("submitButton").addEventListener("click", (e) => {
                 e.preventDefault();
                 e.stopPropagation();
@@ -42,11 +41,12 @@
 
                 $("submitButton").disabled = true;
 
+                const path = new URLSearchParams(window.location.search).get("path");
                 fetch("api/v2/rss/addFeed", {
                         method: "POST",
                         body: new URLSearchParams({
                             url: feedURL,
-                            path: path ? (path + "\\" + feedURL) : ""
+                            path: (((path !== null) && (path.length > 0)) ? `${path}\\${feedURL}` : "")
                         })
                     })
                     .then(async (response) => {
diff --git a/src/webui/www/private/newfolder.html b/src/webui/www/private/newfolder.html
index 9397228194ca..30db4c450f3d 100644
--- a/src/webui/www/private/newfolder.html
+++ b/src/webui/www/private/newfolder.html
@@ -29,7 +29,6 @@
             });
 
             $("folderName").focus();
-            const path = new URI().getData("path");
             $("submitButton").addEventListener("click", (e) => {
                 e.preventDefault();
                 e.stopPropagation();
@@ -43,10 +42,11 @@
 
                 $("submitButton").disabled = true;
 
+                const path = new URLSearchParams(window.location.search).get("path");
                 fetch("api/v2/rss/addFolder", {
                         method: "POST",
                         body: new URLSearchParams({
-                            path: path ? (path + "\\" + folderName) : folderName
+                            path: (((path !== null) && (path.length > 0)) ? `${path}\\${folderName}` : folderName)
                         })
                     })
                     .then(async (response) => {
diff --git a/src/webui/www/private/newtag.html b/src/webui/www/private/newtag.html
index abc9a5c63fa6..a8067fecceb4 100644
--- a/src/webui/www/private/newtag.html
+++ b/src/webui/www/private/newtag.html
@@ -27,8 +27,8 @@
                 }
             });
 
-            const uriAction = window.qBittorrent.Misc.safeTrim(new URI().getData("action"));
-            const uriHashes = window.qBittorrent.Misc.safeTrim(new URI().getData("hashes"));
+            const searchParams = new URLSearchParams(window.location.search);
+            const uriAction = window.qBittorrent.Misc.safeTrim(searchParams.get("action"));
 
             if (uriAction === "create")
                 $("legendText").textContent = "QBT_TR(Tag:)QBT_TR[CONTEXT=TagFilterWidget]";
@@ -52,8 +52,9 @@
                 };
 
                 switch (uriAction) {
-                    case "set":
-                        if (uriHashes === "")
+                    case "set": {
+                        const uriHashes = window.qBittorrent.Misc.safeTrim(searchParams.get("hashes"));
+                        if ((uriHashes === null) || (uriHashes.length <= 0))
                             return;
 
                         fetch("api/v2/torrents/addTags", {
@@ -70,6 +71,7 @@
                                 window.parent.qBittorrent.Client.closeFrameWindow(window);
                             });
                         break;
+                    }
 
                     case "create":
                         if (!verifyTagName(tagName))
diff --git a/src/webui/www/private/rename.html b/src/webui/www/private/rename.html
index 46c6c92daf64..f3f1d119f36e 100644
--- a/src/webui/www/private/rename.html
+++ b/src/webui/www/private/rename.html
@@ -27,9 +27,10 @@
                 }
             });
 
-            const name = new URI().getData("name");
+            const searchParams = new URLSearchParams(window.location.search);
+            const name = searchParams.get("name");
             // set text field to current value
-            if (name)
+            if (name !== null)
                 $("rename").value = name;
 
             $("rename").focus();
@@ -42,8 +43,8 @@
                 if ((name === null) || (name === ""))
                     return;
 
-                const hash = new URI().getData("hash");
-                if (hash) {
+                const hash = searchParams.get("hash");
+                if (hash !== null) {
                     fetch("api/v2/torrents/rename", {
                             method: "POST",
                             body: new URLSearchParams({
diff --git a/src/webui/www/private/rename_feed.html b/src/webui/www/private/rename_feed.html
index 06a5b58f7ef4..d11f41935e92 100644
--- a/src/webui/www/private/rename_feed.html
+++ b/src/webui/www/private/rename_feed.html
@@ -27,7 +27,7 @@
                 }
             });
 
-            const oldPath = new URI().getData("oldPath");
+            const oldPath = new URLSearchParams(window.location.search).get("oldPath");
 
             $("rename").value = oldPath;
             $("rename").focus();
diff --git a/src/webui/www/private/rename_file.html b/src/webui/www/private/rename_file.html
index e61a2a4eeb77..8cddc935b085 100644
--- a/src/webui/www/private/rename_file.html
+++ b/src/webui/www/private/rename_file.html
@@ -28,9 +28,10 @@
                 }
             });
 
-            const hash = new URI().getData("hash");
-            const oldPath = new URI().getData("path");
-            const isFolder = ((new URI().getData("isFolder")) === "true");
+            const searchParams = new URLSearchParams(window.location.search);
+            const hash = searchParams.get("hash");
+            const oldPath = searchParams.get("path");
+            const isFolder = ((searchParams.get("isFolder")) === "true");
 
             const oldName = window.qBittorrent.Filesystem.fileName(oldPath);
             $("rename").value = oldName;
diff --git a/src/webui/www/private/rename_rule.html b/src/webui/www/private/rename_rule.html
index af5d5c6e4552..dc0c39b75a42 100644
--- a/src/webui/www/private/rename_rule.html
+++ b/src/webui/www/private/rename_rule.html
@@ -27,7 +27,7 @@
                 }
             });
 
-            const oldName = new URI().getData("rule");
+            const oldName = new URLSearchParams(window.location.search).get("rule");
 
             $("rename").value = oldName;
             $("rename").focus();
diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js
index 974f29945ca6..36b5568b7b55 100644
--- a/src/webui/www/private/scripts/client.js
+++ b/src/webui/www/private/scripts/client.js
@@ -1656,7 +1656,7 @@ window.addEventListener("DOMContentLoaded", () => {
                     icon: "images/qbittorrent-tray.svg",
                     title: "QBT_TR(Upload local torrent)QBT_TR[CONTEXT=HttpServer]",
                     loadMethod: "iframe",
-                    contentURL: new URI("upload.html").toString(),
+                    contentURL: "upload.html",
                     addClass: "windowFrame", // fixes iframe scrolling on iOS Safari
                     scrollbars: true,
                     maximizable: false,
@@ -1693,13 +1693,16 @@ window.addEventListener("DOMContentLoaded", () => {
                     return;
 
                 const id = "downloadPage";
-                const contentURI = new URI("download.html").setData("urls", urls.map(encodeURIComponent).join("|"));
+                const contentURL = new URL("download.html", window.location);
+                contentURL.search = new URLSearchParams({
+                    urls: urls.map(encodeURIComponent).join("|")
+                });
                 new MochaUI.Window({
                     id: id,
                     icon: "images/qbittorrent-tray.svg",
                     title: "QBT_TR(Download from URLs)QBT_TR[CONTEXT=downloadFromURL]",
                     loadMethod: "iframe",
-                    contentURL: contentURI.toString(),
+                    contentURL: contentURL.toString(),
                     addClass: "windowFrame", // fixes iframe scrolling on iOS Safari
                     scrollbars: true,
                     maximizable: false,
diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js
index e0e6acebba84..c0f34c2c5b60 100644
--- a/src/webui/www/private/scripts/mocha-init.js
+++ b/src/webui/www/private/scripts/mocha-init.js
@@ -179,17 +179,20 @@ const initializeWindows = () => {
 
     showDownloadPage = (urls) => {
         const id = "downloadPage";
-        const contentUri = new URI("download.html");
+        const contentURL = new URL("download.html", window.location);
 
-        if (urls && (urls.length > 0))
-            contentUri.setData("urls", urls.map(encodeURIComponent).join("|"));
+        if (urls && (urls.length > 0)) {
+            contentURL.search = new URLSearchParams({
+                urls: urls.map(encodeURIComponent).join("|")
+            });
+        }
 
         new MochaUI.Window({
             id: id,
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(Download from URLs)QBT_TR[CONTEXT=downloadFromURL]",
             loadMethod: "iframe",
-            contentURL: contentUri.toString(),
+            contentURL: contentURL.toString(),
             addClass: "windowFrame", // fixes iframe scrolling on iOS Safari
             scrollbars: true,
             maximizable: false,
@@ -216,7 +219,7 @@ const initializeWindows = () => {
             title: "QBT_TR(Options)QBT_TR[CONTEXT=OptionsDialog]",
             loadMethod: "xhr",
             toolbar: true,
-            contentURL: new URI("views/preferences.html").toString(),
+            contentURL: "views/preferences.html",
             require: {
                 css: ["css/Tabs.css"]
             },
@@ -242,7 +245,7 @@ const initializeWindows = () => {
             id: id,
             title: "QBT_TR(Manage Cookies)QBT_TR[CONTEXT=CookiesDialog]",
             loadMethod: "xhr",
-            contentURL: new URI("views/cookies.html").toString(),
+            contentURL: "views/cookies.html",
             maximizable: false,
             paddingVertical: 0,
             paddingHorizontal: 0,
@@ -264,7 +267,7 @@ const initializeWindows = () => {
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(Upload local torrent)QBT_TR[CONTEXT=HttpServer]",
             loadMethod: "iframe",
-            contentURL: new URI("upload.html").toString(),
+            contentURL: "upload.html",
             addClass: "windowFrame", // fixes iframe scrolling on iOS Safari
             scrollbars: true,
             maximizable: false,
@@ -280,12 +283,16 @@ const initializeWindows = () => {
     });
 
     globalUploadLimitFN = () => {
+        const contentURL = new URL("uploadlimit.html", window.location);
+        contentURL.search = new URLSearchParams({
+            hashes: "global"
+        });
         new MochaUI.Window({
             id: "uploadLimitPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(Global Upload Speed Limit)QBT_TR[CONTEXT=MainWindow]",
             loadMethod: "iframe",
-            contentURL: new URI("uploadlimit.html").setData("hashes", "global").toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: false,
             maximizable: false,
@@ -298,63 +305,73 @@ const initializeWindows = () => {
 
     uploadLimitFN = () => {
         const hashes = torrentsTable.selectedRowsIds();
-        if (hashes.length) {
-            new MochaUI.Window({
-                id: "uploadLimitPage",
-                icon: "images/qbittorrent-tray.svg",
-                title: "QBT_TR(Torrent Upload Speed Limiting)QBT_TR[CONTEXT=TransferListWidget]",
-                loadMethod: "iframe",
-                contentURL: new URI("uploadlimit.html").setData("hashes", hashes.join("|")).toString(),
-                scrollbars: false,
-                resizable: false,
-                maximizable: false,
-                paddingVertical: 0,
-                paddingHorizontal: 0,
-                width: 424,
-                height: 100
-            });
-        }
+        if (hashes.length <= 0)
+            return;
+
+        const contentURL = new URL("uploadlimit.html", window.location);
+        contentURL.search = new URLSearchParams({
+            hashes: hashes.join("|")
+        });
+        new MochaUI.Window({
+            id: "uploadLimitPage",
+            icon: "images/qbittorrent-tray.svg",
+            title: "QBT_TR(Torrent Upload Speed Limiting)QBT_TR[CONTEXT=TransferListWidget]",
+            loadMethod: "iframe",
+            contentURL: contentURL.toString(),
+            scrollbars: false,
+            resizable: false,
+            maximizable: false,
+            paddingVertical: 0,
+            paddingHorizontal: 0,
+            width: 424,
+            height: 100
+        });
     };
 
     shareRatioFN = () => {
         const hashes = torrentsTable.selectedRowsIds();
-        if (hashes.length) {
-            let shareRatio = null;
-            let torrentsHaveSameShareRatio = true;
-
-            // check if all selected torrents have same share ratio
-            for (let i = 0; i < hashes.length; ++i) {
-                const hash = hashes[i];
-                const row = torrentsTable.getRow(hash).full_data;
-                const origValues = row.ratio_limit + "|" + row.seeding_time_limit + "|" + row.inactive_seeding_time_limit + "|"
-                    + row.max_ratio + "|" + row.max_seeding_time + "|" + row.max_inactive_seeding_time;
-
-                // initialize value
-                if (shareRatio === null)
-                    shareRatio = origValues;
-
-                if (origValues !== shareRatio) {
-                    torrentsHaveSameShareRatio = false;
-                    break;
-                }
+        if (hashes.length <= 0)
+            return;
+
+        let shareRatio = null;
+        let torrentsHaveSameShareRatio = true;
+
+        // check if all selected torrents have same share ratio
+        for (let i = 0; i < hashes.length; ++i) {
+            const hash = hashes[i];
+            const row = torrentsTable.getRow(hash).full_data;
+            const origValues = row.ratio_limit + "|" + row.seeding_time_limit + "|" + row.inactive_seeding_time_limit + "|"
+                + row.max_ratio + "|" + row.max_seeding_time + "|" + row.max_inactive_seeding_time;
+
+            // initialize value
+            if (shareRatio === null)
+                shareRatio = origValues;
+
+            if (origValues !== shareRatio) {
+                torrentsHaveSameShareRatio = false;
+                break;
             }
+        }
 
+        const contentURL = new URL("shareratio.html", window.location);
+        contentURL.search = new URLSearchParams({
+            hashes: hashes.join("|"),
             // if all torrents have same share ratio, display that share ratio. else use the default
-            const orig = torrentsHaveSameShareRatio ? shareRatio : "";
-            new MochaUI.Window({
-                id: "shareRatioPage",
-                icon: "images/qbittorrent-tray.svg",
-                title: "QBT_TR(Torrent Upload/Download Ratio Limiting)QBT_TR[CONTEXT=UpDownRatioDialog]",
-                loadMethod: "iframe",
-                contentURL: new URI("shareratio.html").setData("hashes", hashes.join("|")).setData("orig", orig).toString(),
-                scrollbars: false,
-                maximizable: false,
-                paddingVertical: 0,
-                paddingHorizontal: 0,
-                width: 424,
-                height: 220
-            });
-        }
+            orig: torrentsHaveSameShareRatio ? shareRatio : ""
+        });
+        new MochaUI.Window({
+            id: "shareRatioPage",
+            icon: "images/qbittorrent-tray.svg",
+            title: "QBT_TR(Torrent Upload/Download Ratio Limiting)QBT_TR[CONTEXT=UpDownRatioDialog]",
+            loadMethod: "iframe",
+            contentURL: contentURL.toString(),
+            scrollbars: false,
+            maximizable: false,
+            paddingVertical: 0,
+            paddingHorizontal: 0,
+            width: 424,
+            height: 220
+        });
     };
 
     toggleSequentialDownloadFN = () => {
@@ -412,12 +429,16 @@ const initializeWindows = () => {
     };
 
     globalDownloadLimitFN = () => {
+        const contentURL = new URL("downloadlimit.html", window.location);
+        contentURL.search = new URLSearchParams({
+            hashes: "global"
+        });
         new MochaUI.Window({
             id: "downloadLimitPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(Global Download Speed Limit)QBT_TR[CONTEXT=MainWindow]",
             loadMethod: "iframe",
-            contentURL: new URI("downloadlimit.html").setData("hashes", "global").toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: false,
             maximizable: false,
@@ -435,7 +456,7 @@ const initializeWindows = () => {
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(Statistics)QBT_TR[CONTEXT=StatsDialog]",
             loadMethod: "xhr",
-            contentURL: new URI("views/statistics.html").toString(),
+            contentURL: "views/statistics.html",
             maximizable: false,
             padding: 10,
             width: loadWindowWidth(id, 285),
@@ -448,22 +469,27 @@ const initializeWindows = () => {
 
     downloadLimitFN = () => {
         const hashes = torrentsTable.selectedRowsIds();
-        if (hashes.length) {
-            new MochaUI.Window({
-                id: "downloadLimitPage",
-                icon: "images/qbittorrent-tray.svg",
-                title: "QBT_TR(Torrent Download Speed Limiting)QBT_TR[CONTEXT=TransferListWidget]",
-                loadMethod: "iframe",
-                contentURL: new URI("downloadlimit.html").setData("hashes", hashes.join("|")).toString(),
-                scrollbars: false,
-                resizable: false,
-                maximizable: false,
-                paddingVertical: 0,
-                paddingHorizontal: 0,
-                width: 424,
-                height: 100
-            });
-        }
+        if (hashes.length <= 0)
+            return;
+
+        const contentURL = new URL("downloadlimit.html", window.location);
+        contentURL.search = new URLSearchParams({
+            hashes: hashes.join("|")
+        });
+        new MochaUI.Window({
+            id: "downloadLimitPage",
+            icon: "images/qbittorrent-tray.svg",
+            title: "QBT_TR(Torrent Download Speed Limiting)QBT_TR[CONTEXT=TransferListWidget]",
+            loadMethod: "iframe",
+            contentURL: contentURL.toString(),
+            scrollbars: false,
+            resizable: false,
+            maximizable: false,
+            paddingVertical: 0,
+            paddingHorizontal: 0,
+            width: 424,
+            height: 100
+        });
     };
 
     deleteSelectedTorrentsFN = (forceDeleteFiles = false) => {
@@ -625,49 +651,58 @@ const initializeWindows = () => {
 
     setLocationFN = () => {
         const hashes = torrentsTable.selectedRowsIds();
-        if (hashes.length) {
-            const hash = hashes[0];
-            const row = torrentsTable.getRow(hash);
+        if (hashes.length <= 0)
+            return;
 
-            new MochaUI.Window({
-                id: "setLocationPage",
-                icon: "images/qbittorrent-tray.svg",
-                title: "QBT_TR(Set location)QBT_TR[CONTEXT=TransferListWidget]",
-                loadMethod: "iframe",
-                contentURL: new URI("setlocation.html").setData("hashes", hashes.join("|")).setData("path", encodeURIComponent(row.full_data.save_path)).toString(),
-                scrollbars: false,
-                resizable: true,
-                maximizable: false,
-                paddingVertical: 0,
-                paddingHorizontal: 0,
-                width: 400,
-                height: 130
-            });
-        }
+        const contentURL = new URL("setlocation.html", window.location);
+        contentURL.search = new URLSearchParams({
+            hashes: hashes.join("|"),
+            path: encodeURIComponent(torrentsTable.getRow(hashes[0]).full_data.save_path)
+        });
+        new MochaUI.Window({
+            id: "setLocationPage",
+            icon: "images/qbittorrent-tray.svg",
+            title: "QBT_TR(Set location)QBT_TR[CONTEXT=TransferListWidget]",
+            loadMethod: "iframe",
+            contentURL: contentURL.toString(),
+            scrollbars: false,
+            resizable: true,
+            maximizable: false,
+            paddingVertical: 0,
+            paddingHorizontal: 0,
+            width: 400,
+            height: 130
+        });
     };
 
     renameFN = () => {
         const hashes = torrentsTable.selectedRowsIds();
-        if (hashes.length === 1) {
-            const hash = hashes[0];
-            const row = torrentsTable.getRow(hash);
-            if (row) {
-                new MochaUI.Window({
-                    id: "renamePage",
-                    icon: "images/qbittorrent-tray.svg",
-                    title: "QBT_TR(Rename)QBT_TR[CONTEXT=TransferListWidget]",
-                    loadMethod: "iframe",
-                    contentURL: new URI("rename.html").setData("hash", hash).setData("name", row.full_data.name).toString(),
-                    scrollbars: false,
-                    resizable: true,
-                    maximizable: false,
-                    paddingVertical: 0,
-                    paddingHorizontal: 0,
-                    width: 400,
-                    height: 100
-                });
-            }
-        }
+        if (hashes.length !== 1)
+            return;
+
+        const row = torrentsTable.getRow(hashes[0]);
+        if (!row)
+            return;
+
+        const contentURL = new URL("rename.html", window.location);
+        contentURL.search = new URLSearchParams({
+            hash: hashes[0],
+            name: row.full_data.name
+        });
+        new MochaUI.Window({
+            id: "renamePage",
+            icon: "images/qbittorrent-tray.svg",
+            title: "QBT_TR(Rename)QBT_TR[CONTEXT=TransferListWidget]",
+            loadMethod: "iframe",
+            contentURL: contentURL.toString(),
+            scrollbars: false,
+            resizable: true,
+            maximizable: false,
+            paddingVertical: 0,
+            paddingHorizontal: 0,
+            width: 400,
+            height: 100
+        });
     };
 
     renameFilesFN = () => {
@@ -784,12 +819,17 @@ const initializeWindows = () => {
         if (hashes.length <= 0)
             return;
 
+        const contentURL = new URL("newcategory.html", window.location);
+        contentURL.search = new URLSearchParams({
+            action: "set",
+            hashes: hashes.join("|")
+        });
         new MochaUI.Window({
             id: "newCategoryPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(New Category)QBT_TR[CONTEXT=TransferListWidget]",
             loadMethod: "iframe",
-            contentURL: new URI("newcategory.html").setData("action", "set").setData("hashes", hashes.join("|")).toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: true,
             maximizable: false,
@@ -821,12 +861,16 @@ const initializeWindows = () => {
     };
 
     createCategoryFN = () => {
+        const contentURL = new URL("newcategory.html", window.location);
+        contentURL.search = new URLSearchParams({
+            action: "create"
+        });
         new MochaUI.Window({
             id: "newCategoryPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(New Category)QBT_TR[CONTEXT=CategoryFilterWidget]",
             loadMethod: "iframe",
-            contentURL: new URI("newcategory.html").setData("action", "create").toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: true,
             maximizable: false,
@@ -838,12 +882,17 @@ const initializeWindows = () => {
     };
 
     createSubcategoryFN = (category) => {
+        const contentURL = new URL("newcategory.html", window.location);
+        contentURL.search = new URLSearchParams({
+            action: "createSubcategory",
+            categoryName: `${category}/`
+        });
         new MochaUI.Window({
             id: "newSubcategoryPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(New Category)QBT_TR[CONTEXT=CategoryFilterWidget]",
             loadMethod: "iframe",
-            contentURL: new URI("newcategory.html").setData("action", "createSubcategory").setData("categoryName", `${category}/`).toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: true,
             maximizable: false,
@@ -855,12 +904,18 @@ const initializeWindows = () => {
     };
 
     editCategoryFN = (category) => {
+        const contentURL = new URL("newcategory.html", window.location);
+        contentURL.search = new URLSearchParams({
+            action: "edit",
+            categoryName: category,
+            savePath: categoryMap.get(category).savePath
+        });
         new MochaUI.Window({
             id: "editCategoryPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(Edit Category)QBT_TR[CONTEXT=TransferListWidget]",
             loadMethod: "iframe",
-            contentURL: new URI("newcategory.html").setData("action", "edit").setData("categoryName", category).setData("savePath", categoryMap.get(category).savePath).toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: true,
             maximizable: false,
@@ -913,12 +968,17 @@ const initializeWindows = () => {
         if (hashes.length <= 0)
             return;
 
+        const contentURL = new URL("newtag.html", window.location);
+        contentURL.search = new URLSearchParams({
+            action: "set",
+            hashes: hashes.join("|")
+        });
         new MochaUI.Window({
             id: "newTagPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(Add tags)QBT_TR[CONTEXT=TransferListWidget]",
             loadMethod: "iframe",
-            contentURL: new URI("newtag.html").setData("action", "set").setData("hashes", hashes.join("|")).toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: true,
             maximizable: false,
@@ -956,12 +1016,16 @@ const initializeWindows = () => {
     };
 
     createTagFN = () => {
+        const contentURL = new URL("newtag.html", window.location);
+        contentURL.search = new URLSearchParams({
+            action: "create"
+        });
         new MochaUI.Window({
             id: "newTagPage",
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(New Tag)QBT_TR[CONTEXT=TagFilterWidget]",
             loadMethod: "iframe",
-            contentURL: new URI("newtag.html").setData("action", "create").toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: true,
             maximizable: false,
@@ -1002,12 +1066,16 @@ const initializeWindows = () => {
         if ((trackerHost === TRACKERS_ALL) || (trackerHost === TRACKERS_TRACKERLESS))
             return;
 
-        const trackerURLs = [...trackerMap.get(trackerHost).keys()].map(encodeURIComponent).join("|");
+        const contentURL = new URL("confirmtrackerdeletion.html", window.location);
+        contentURL.search = new URLSearchParams({
+            host: trackerHost,
+            urls: [...trackerMap.get(trackerHost).keys()].map(encodeURIComponent).join("|")
+        });
         new MochaUI.Window({
             id: "confirmDeletionPage",
             title: "QBT_TR(Remove tracker)QBT_TR[CONTEXT=confirmDeletionDlg]",
             loadMethod: "iframe",
-            contentURL: new URI("confirmtrackerdeletion.html").setData("host", trackerHost).setData("urls", trackerURLs).toString(),
+            contentURL: contentURL.toString(),
             scrollbars: false,
             resizable: true,
             maximizable: false,
@@ -1099,7 +1167,10 @@ const initializeWindows = () => {
                 continue;
 
             const name = row.full_data.name;
-            const url = new URI("api/v2/torrents/export").setData("hash", hash).toString();
+            const url = new URL("api/v2/torrents/export", window.location);
+            url.search = new URLSearchParams({
+                hash: hash
+            });
 
             // download response to file
             await window.qBittorrent.Misc.downloadFile(url, `${name}.torrent`, "QBT_TR(Unable to export torrent file)QBT_TR[CONTEXT=MainWindow]");
@@ -1190,7 +1261,7 @@ const initializeWindows = () => {
             icon: "images/qbittorrent-tray.svg",
             title: "QBT_TR(About qBittorrent)QBT_TR[CONTEXT=AboutDialog]",
             loadMethod: "xhr",
-            contentURL: new URI("views/about.html").toString(),
+            contentURL: "views/about.html",
             require: {
                 css: ["css/Tabs.css"]
             },
diff --git a/src/webui/www/private/scripts/prop-peers.js b/src/webui/www/private/scripts/prop-peers.js
index d4d09205c827..a3fd66f9064f 100644
--- a/src/webui/www/private/scripts/prop-peers.js
+++ b/src/webui/www/private/scripts/prop-peers.js
@@ -56,9 +56,11 @@ window.qBittorrent.PropPeers ??= (() => {
             clearTimeout(loadTorrentPeersTimer);
             return;
         }
-        const url = new URI("api/v2/sync/torrentPeers")
-            .setData("rid", syncTorrentPeersLastResponseId)
-            .setData("hash", current_hash);
+        const url = new URL("api/v2/sync/torrentPeers", window.location);
+        url.search = new URLSearchParams({
+            hash: current_hash,
+            rid: syncTorrentPeersLastResponseId,
+        });
         fetch(url, {
                 method: "GET",
                 cache: "no-store"
diff --git a/src/webui/www/private/setlocation.html b/src/webui/www/private/setlocation.html
index 6b45214ef9c6..1455340df5af 100644
--- a/src/webui/www/private/setlocation.html
+++ b/src/webui/www/private/setlocation.html
@@ -27,10 +27,11 @@
                 }
             });
 
-            const path = new URI().getData("path");
+            const searchParams = new URLSearchParams(window.location.search);
+            const path = searchParams.get("path");
 
             // set text field to current value
-            if (path)
+            if (path !== null)
                 $("setLocation").value = decodeURIComponent(path);
 
             $("setLocation").focus();
@@ -48,7 +49,7 @@
                 fetch("api/v2/torrents/setLocation", {
                         method: "POST",
                         body: new URLSearchParams({
-                            hashes: new URI().getData("hashes"),
+                            hashes: searchParams.get("hashes"),
                             location: location
                         })
                     })
diff --git a/src/webui/www/private/shareratio.html b/src/webui/www/private/shareratio.html
index ce5131d5bbbc..c764e256b416 100644
--- a/src/webui/www/private/shareratio.html
+++ b/src/webui/www/private/shareratio.html
@@ -30,8 +30,8 @@
                 }
             });
 
-            const hashesList = new URI().getData("hashes").split("|");
-            const origValues = new URI().getData("orig").split("|");
+            const searchParams = new URLSearchParams(window.location.search);
+            const origValues = searchParams.get("orig").split("|");
 
             const values = {
                 ratioLimit: window.qBittorrent.Misc.friendlyFloat(origValues[0], 2),
@@ -103,7 +103,7 @@
                 fetch("api/v2/torrents/setShareLimits", {
                         method: "POST",
                         body: new URLSearchParams({
-                            hashes: hashesList.join("|"),
+                            hashes: searchParams.get("hashes"),
                             ratioLimit: ratioLimitValue,
                             seedingTimeLimit: seedingTimeLimitValue,
                             inactiveSeedingTimeLimit: inactiveSeedingTimeLimitValue
diff --git a/src/webui/www/private/uploadlimit.html b/src/webui/www/private/uploadlimit.html
index 164da21f812e..ed672cd47942 100644
--- a/src/webui/www/private/uploadlimit.html
+++ b/src/webui/www/private/uploadlimit.html
@@ -46,7 +46,7 @@
             }
         });
 
-        const hashes = new URI().getData("hashes").split("|");
+        const hashes = new URLSearchParams(window.location.search).get("hashes").split("|");
         const setUpLimit = () => {
             const limit = Number($("uplimitUpdatevalue").value) * 1024;
             if (hashes[0] === "global") {
diff --git a/src/webui/www/private/views/log.html b/src/webui/www/private/views/log.html
index ca98f3dda390..a988e5ba591e 100644
--- a/src/webui/www/private/views/log.html
+++ b/src/webui/www/private/views/log.html
@@ -340,20 +340,23 @@
                 curTab = currentSelectedTab;
 
             let url;
-            if (curTab === "main") {
-                url = new URI("api/v2/log/main");
-                url.setData({
-                    normal: selectedLogLevels.includes("1"),
-                    info: selectedLogLevels.includes("2"),
-                    warning: selectedLogLevels.includes("4"),
-                    critical: selectedLogLevels.includes("8")
-                });
-            }
-            else {
-                url = new URI("api/v2/log/peers");
+            switch (curTab) {
+                case "main":
+                    url = new URL("api/v2/log/main", window.location);
+                    url.search = new URLSearchParams({
+                        normal: selectedLogLevels.includes("1"),
+                        info: selectedLogLevels.includes("2"),
+                        warning: selectedLogLevels.includes("4"),
+                        critical: selectedLogLevels.includes("8")
+                    });
+                    break;
+
+                case "peer":
+                    url = new URL("api/v2/log/peers", window.location);
+                    break;
             }
 
-            url.setData("last_known_id", tableInfo[curTab].last_id);
+            url.searchParams.set("last_known_id", tableInfo[curTab].last_id);
             tableInfo[curTab].progress = true;
 
             fetch(url, {
diff --git a/src/webui/www/private/views/rss.html b/src/webui/www/private/views/rss.html
index 849897709a6d..ff7845b90e5f 100644
--- a/src/webui/www/private/views/rss.html
+++ b/src/webui/www/private/views/rss.html
@@ -743,12 +743,17 @@
         };
 
         const editUrl = (path, url) => {
+            const contentURL = new URL("editfeedurl.html", window.location);
+            contentURL.search = new URLSearchParams({
+                path: path,
+                url: url
+            });
             new MochaUI.Window({
                 id: "editFeedURL",
                 icon: "images/qbittorrent-tray.svg",
                 title: "QBT_TR(Please type a RSS feed URL)QBT_TR[CONTEXT=RSSWidget]",
                 loadMethod: "iframe",
-                contentURL: new URI("editfeedurl.html").setData("path", path).setData("url", url).toString(),
+                contentURL: contentURL.toString(),
                 scrollbars: false,
                 resizable: false,
                 maximizable: false,