Преглед на файлове

use XHR as first fallback when receiving a 403

Gildas преди 7 години
родител
ревизия
2e56cbc1ea
променени са 1 файла, в които са добавени 33 реда и са изтрити 1 реда
  1. 33 1
      lib/fetch/content/fetch.js

+ 33 - 1
lib/fetch/content/fetch.js

@@ -18,7 +18,7 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global browser, fetch */
+/* global browser, fetch, XMLHttpRequest */
 
 this.superFetch = this.superFetch || (() => {
 
@@ -29,6 +29,9 @@ this.superFetch = this.superFetch || (() => {
 				if (response.status == 403) {
 					response = await fetch(url, { credentials: "same-origin", cache: "force-cache" });
 				}
+				if (response.status == 403) {
+					response = await xhrFetch(url);
+				}
 				if (response.status == 403) {
 					response = await fetch(url, { credentials: "include", cache: "force-cache" });
 				}
@@ -46,6 +49,7 @@ this.superFetch = this.superFetch || (() => {
 			catch (error) {
 				const responseFetch = await sendMessage({ method: "fetch", url });
 				return {
+					status: responseFetch.status,
 					headers: { get: headerName => responseFetch.headers[headerName] },
 					arrayBuffer: async () => {
 						const response = await sendMessage({ method: "fetch.array", requestId: responseFetch.responseId });
@@ -66,4 +70,32 @@ this.superFetch = this.superFetch || (() => {
 		}
 	}
 
+	function xhrFetch(url) {
+		return new Promise((resolve, reject) => {
+			const xhrRequest = new XMLHttpRequest();
+			xhrRequest.responseType = "arraybuffer";
+			xhrRequest.onerror = event => reject(new Error(event.details));
+			xhrRequest.onreadystatechange = () => {
+				if (xhrRequest.readyState == XMLHttpRequest.HEADERS_RECEIVED || xhrRequest.readyState == XMLHttpRequest.DONE) {
+					const headers = new Map();
+					headers.set("content-type", xhrRequest.getResponseHeader("Content-Type"));
+					resolve({
+						status: xhrRequest.status,
+						headers,
+						arrayBuffer: () => new Promise((resolve, reject) => {
+							xhrRequest.onerror = event => reject(new Error(event.details));
+							if (xhrRequest.readyState == XMLHttpRequest.DONE) {
+								resolve(xhrRequest.response);
+							} else {
+								xhrRequest.onload = () => resolve(xhrRequest.response);
+							}
+						})
+					});
+				}
+			};
+			xhrRequest.open("GET", url, true);
+			xhrRequest.send();
+		});
+	}
+
 })();