首页 > 解决方案 > XMLHttpRequest 和 Service Worker API 有什么区别来预加载我的 Web 应用程序的资产

问题描述

我有下面的代码将特定文件预加载到缓存中,并且使用XMLHttpRequest.

问题是如果我只想在 Chrome 上使用我的方法和使用Service Worker API之间有什么区别。

与使用相比,Service Worker API 的优缺点是XMLHttpRequest什么?

如果他们都将数据保存到浏览器的缓存中,为什么我应该使用 Service Worker?

preload();

function preload(){

(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
	typeof define === 'function' && define.amd ? define(factory) :
	(global.Preload = factory());
}(this, (function () { 'use strict';

	function preloadOne(url, done) {
		const xhr = new XMLHttpRequest();
		xhr.open('GET', url, true);
		xhr.responseType = 'blob';
		xhr.onprogress = event => {
			if (!event.lengthComputable) return false
			let item = this.getItemByUrl(event.target.responseURL);
			item.completion = parseInt((event.loaded / event.total) * 100);
			item.downloaded = event.loaded;
			item.total = event.total;
			this.updateProgressBar(item);
		};
		xhr.onload = event => {
			let type = event.target.response.type;
			let blob = new Blob([event.target.response], { type: type });
			let url = URL.createObjectURL(blob);
			let responseURL = event.target.responseURL;
			let item = this.getItemByUrl(responseURL);
			item.blobUrl = url;
			item.fileName = responseURL.substring(responseURL.lastIndexOf('/') + 1);
			item.type = type;
			item.size = blob.size;
			done(item);
		};
		
		xhr.onerror = event => {
        console.log('Error has happend so we restart the preloading..');
        preload();
        };
        
		xhr.send();
	}

	function updateProgressBar(item) {
		var sumCompletion = 0;
		var maxCompletion = this.status.length * 100;

		for (var itemStatus of this.status) {
			if (itemStatus.completion) {
				sumCompletion += itemStatus.completion;
			}
		}
		var totalCompletion = parseInt((sumCompletion / maxCompletion) * 100);

		if (!isNaN(totalCompletion)) {
			this.onprogress({
				progress: totalCompletion,
				item: item
			});
		}
	}

	function getItemByUrl(rawUrl) {
	    for (var item of this.status) {
	        if (item.url == rawUrl) return item
	    }
	}

	function fetch(list) {	
		return new Promise((resolve, reject) => {
			this.loaded = list.length;
			for (let item of list) {
				this.status.push({ url: item });
				this.preloadOne(item, item => {
					this.onfetched(item);
					this.loaded--;
					if (this.loaded == 0) {
						this.oncomplete(this.status);
						resolve(this.status);
					}
				});
			}
		})
	}

	function Preload() {
		return {
			status: [],
			loaded: false,
			onprogress: () => {},
			oncomplete: () => {},
			onfetched: () => {},
			fetch,
			updateProgressBar,
			preloadOne,
			getItemByUrl
		}
	}

	return Preload;

})));


	const preload = Preload();

	preload.fetch([
	    'https://round-arm-authority.000webhostapp.com/Ultimate%20Video%20Hack/videos/vid1.mp4'

	]).then(items => {
	  // use either a promise or 'oncomplete'
	  console.log(items);
	});

	preload.oncomplete = items => {
	  console.log(items);
	}

	preload.onprogress = event => {
	  console.log(event.progress + '%');
	}

	preload.onfetched = item => {
	  console.log(item);
	}
	
};

标签: javascriptxmlhttprequestservice-worker

解决方案


服务工作者允许您拦截导航请求并直接从缓存中提供 HTML,同时在您将更改部署到站点时仍然具有用于更新该 HTML 的带外机制。

Service Worker 允许您对子资源使用比 HTTP 缓存所允许的更复杂的更新和回退策略


推荐阅读