Просмотр исходного кода

take redirectis into account when resolving URLs

Gildas 7 лет назад
Родитель
Сommit
c4dd2cc118
2 измененных файлов с 27 добавлено и 19 удалено
  1. 13 10
      lib/single-file/single-file-browser.js
  2. 14 9
      lib/single-file/single-file-core.js

+ 13 - 10
lib/single-file/single-file-browser.js

@@ -66,8 +66,11 @@ this.SingleFile = this.SingleFile || (() => {
 			}
 			try {
 				resourceContent = await fetchResource(resourceURL);
+				if (resourceContent.url) {
+					resourceURL = resourceContent.url;
+				}
 			} catch (error) {
-				return options && options.asDataURI ? "data:base64," : "";
+				return { data: options && options.asDataURI ? "data:base64," : "", resourceURL };
 			}
 			let contentType = resourceContent.headers && resourceContent.headers.get("content-type");
 			let charset;
@@ -92,7 +95,7 @@ this.SingleFile = this.SingleFile || (() => {
 					}
 					const buffer = await resourceContent.arrayBuffer();
 					if (options.maxResourceSizeEnabled && buffer.byteLength > options.maxResourceSize * ONE_MB) {
-						return "data:base64,";
+						return { data: "data:base64,", resourceURL };
 					} else {
 						const reader = new FileReader();
 						reader.readAsDataURL(new Blob([buffer], { type: contentType }));
@@ -100,14 +103,14 @@ this.SingleFile = this.SingleFile || (() => {
 							reader.addEventListener("load", () => resolve(reader.result), false);
 							reader.addEventListener("error", reject, false);
 						});
-						return dataURI;
+						return { data: dataURI, resourceURL };
 					}
 				} catch (error) {
-					return "data:base64,";
+					return { data: "data:base64,", resourceURL };
 				}
 			} else {
 				if (resourceContent.status >= 400 || (options.validateTextContentType && contentType && !contentType.startsWith(PREFIX_CONTENT_TYPE_TEXT))) {
-					return "";
+					return { data: "", resourceURL };
 				}
 				if (!charset) {
 					const matchCharset = contentType && contentType.match(/\s*;\s*charset\s*=\s*"?([^";]*)"?(;|$)/i);
@@ -122,21 +125,21 @@ this.SingleFile = this.SingleFile || (() => {
 				try {
 					buffer = await resourceContent.arrayBuffer();
 				} catch (error) {
-					return "";
+					return { data: "", resourceURL };
 				}
 				if (DEBUG) {
 					log("  // ENDED   download url =", resourceURL, "delay =", Date.now() - startTime);
 				}
 				if (options.maxResourceSizeEnabled && buffer.byteLength > options.maxResourceSize * ONE_MB) {
-					return "";
+					return { data: "", resourceURL };
 				} else {
 					try {
-						return new TextDecoder(charset).decode(buffer);
+						return { data: new TextDecoder(charset).decode(buffer), resourceURL };
 					} catch (error) {
 						try {
-							return new TextDecoder("utf-8").decode(buffer);
+							return { data: new TextDecoder("utf-8").decode(buffer), resourceURL };
 						} catch (error) {
-							return "";
+							return { data: "", resourceURL };
 						}
 					}
 				}

+ 14 - 9
lib/single-file/single-file-core.js

@@ -283,10 +283,10 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				const [resourceURL, asDataURI] = JSON.parse(requestKey);
 				const resourceRequests = this.requests.get(requestKey);
 				try {
-					const resourceContent = await Download.getContent(resourceURL, { asDataURI, maxResourceSize: options.maxResourceSize, maxResourceSizeEnabled: options.maxResourceSizeEnabled });
+					const content = await Download.getContent(resourceURL, { asDataURI, maxResourceSize: options.maxResourceSize, maxResourceSizeEnabled: options.maxResourceSizeEnabled });
 					indexResource = indexResource + 1;
 					onloadListener({ index: indexResource, url: resourceURL });
-					resourceRequests.forEach(resourceRequest => resourceRequest.resolve({ content: resourceContent, indexResource, duplicate: Boolean(resourceRequests.length > 1) }));
+					resourceRequests.forEach(resourceRequest => resourceRequest.resolve({ content: content.data, indexResource, duplicate: Boolean(resourceRequests.length > 1) }));
 				} catch (error) {
 					indexResource = indexResource + 1;
 					onloadListener({ index: indexResource, url: resourceURL });
@@ -325,8 +325,11 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		async loadPage(pageContent) {
+			let resourceURL;
 			if (!pageContent || this.options.saveRawPage) {
-				pageContent = await Download.getContent(this.baseURI, { asDataURI: false, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled });
+				const content = await Download.getContent(this.baseURI, { asDataURI: false, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled });
+				pageContent = content.data;
+				this.baseURI = this.options.url = resourceURL;
 			}
 			this.doc = DOM.createDoc(pageContent, this.baseURI);
 			this.onEventAttributeNames = DOM.getOnEventAttributeNames(this.doc);
@@ -866,8 +869,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			await Promise.all(Array.from(this.doc.querySelectorAll("script[src]")).map(async scriptElement => {
 				if (scriptElement.src) {
 					this.stats.add("processed", "scripts", 1);
-					const scriptContent = await Download.getContent(scriptElement.src, { asDataURI: false, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled });
-					scriptElement.textContent = scriptContent.replace(/<\//gi, "<\\/").replace(/\/>/gi, "\\/>");
+					const content = await Download.getContent(scriptElement.src, { asDataURI: false, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled });
+					scriptElement.textContent = content.data.replace(/<\//gi, "<\\/").replace(/\/>/gi, "\\/>");
 				}
 				scriptElement.removeAttribute("src");
 			}));
@@ -1171,8 +1174,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 						}
 						if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
 							const downloadOptions = { asDataURI: false, maxResourceSize: options.maxResourceSize, maxResourceSizeEnabled: options.maxResourceSizeEnabled, validateTextContentType: true };
-							let importedStylesheetContent = await Download.getContent(resourceURL, downloadOptions);
-							importedStylesheetContent = DomUtil.removeCssComments(importedStylesheetContent);
+							const content = await Download.getContent(resourceURL, downloadOptions);
+							resourceURL = content.resourceURL;
+							let importedStylesheetContent = DomUtil.removeCssComments(content.data);
 							if (options.compressCSS) {
 								importedStylesheetContent = DOM.compressCSS(importedStylesheetContent);
 							}
@@ -1229,8 +1233,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			resourceURL = DomUtil.normalizeURL(resourceURL);
 			if (resourceURL && resourceURL != baseURI && resourceURL != ABOUT_BLANK_URI) {
 				const downloadOptions = { asDataURI: false, maxResourceSize: options.maxResourceSize, maxResourceSizeEnabled: options.maxResourceSizeEnabled, charset: options.charset };
-				let stylesheetContent = await Download.getContent(resourceURL, downloadOptions);
-				stylesheetContent = DomUtil.removeCssComments(stylesheetContent);
+				const content = await Download.getContent(resourceURL, downloadOptions);
+				resourceURL = content.resourceURL;
+				let stylesheetContent = DomUtil.removeCssComments(content.data);
 				if (options.compressCSS) {
 					stylesheetContent = DOM.compressCSS(stylesheetContent);
 				}