<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>JavaScript实现HTML页面图片打包下载</title> </head> <body>
JavaScript实现HTML页面图片打包下载
在Web开发中,我们经常需要将页面中的图片打包下载。本文将介绍如何使用JavaScript结合JSZip和FileSaver.js库,实现将HTML页面中的所有图片一键打包下载为ZIP文件。
实现原理
要实现HTML页面中图片的打包下载,主要分为以下几个步骤:
- 获取页面中所有图片的URL地址
- 使用XMLHttpRequest或fetch API下载每个图片
- 使用JSZip库创建ZIP文件并将图片添加进去
- 使用FileSaver.js库将ZIP文件保存到本地
准备工作
首先,需要在页面中引入JSZip和FileSaver.js库:
<!-- 引入JSZip库 -->
[removed][removed]
<!-- 引入FileSaver.js库 -->
[removed][removed]
实现代码
基础版本:下载页面所有图片
/**
* 打包下载页面中的所有图片
*/
function downloadAllImages() {
// 获取页面中的所有图片元素
var images = document.getElementsByTagName('img');
// 创建JSZip实例
var zip = new JSZip();
// 用于跟踪已完成的请求数量
var completed = 0;
var total = images.length;
if (total === 0) {
alert('页面中没有找到图片!');
return;
}
// 遍历所有图片元素
for (var i = 0; i < total xss=removed xss=removed xss=removed xhr.responseType = 'blob' xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed>
增强版本:支持筛选和更完善的处理
/**
* 增强版图片下载器
* @param {Object} options - 配置选项
*/
function ImageDownloader(options) {
this.options = Object.assign({
selector: 'img', // 图片选择器
zipFileName: 'images.zip', // 默认ZIP文件名
timeout: 30000, // 请求超时时间
onProgress: null, // 进度回调
onComplete: null, // 完成回调
onError: null, // 错误回调
filter: null, // 图片过滤函数
maxSize: 10 * 1024 * 1024 // 单张图片最大大小(10MB)
}, options || {});
this.zip = new JSZip();
this.images = [];
this.results = [];
}
ImageDownloader.prototype = {
/**
* 初始化,获取符合条件的图片列表
*/
init: function() {
var elements = document.querySelectorAll(this.options.selector);
for (var i = 0; i < elements xss=removed xss=removed> this.options.maxSize) {
console.warn('图片过大,已跳过: ' + blob.size + ' bytes');
return false;
}
return true;
},
/**
* 下载单张图片
*/
downloadImage: function(imageInfo) {
var self = this;
return new Promise(function(resolve) {
var xhr = new XMLHttpRequest();
xhr.open('GET', imageInfo.url, true);
xhr.responseType = 'blob';
xhr.timeout = self.options.timeout;
xhr.onload = function() {
if (this.status === 200) {
var contentType = this.response.type || 'image/jpeg';
var extension = self.getExtensionFromMime(contentType);
var result = {
success: true,
url: imageInfo.url,
index: imageInfo.index,
blob: this.response,
extension: extension
};
// 验证文件大小
if (self.validateSize(this.response)) {
self.zip.file('image_' + (imageInfo.index + 1) + extension, this.response);
}
resolve(result);
} else {
resolve({
success: false,
url: imageInfo.url,
index: imageInfo.index,
error: 'HTTP ' + this.status
});
}
};
xhr.onerror = function() {
resolve({
success: false,
url: imageInfo.url,
index: imageInfo.index,
error: 'Network Error'
});
};
xhr.ontimeout = function() {
resolve({
success: false,
url: imageInfo.url,
index: imageInfo.index,
error: 'Timeout'
});
};
xhr.send();
});
},
/**
* 批量下载所有图片
*/
downloadAll: function() {
var self = this;
var total = this.images.length;
if (total === 0) {
alert('没有找到符合条件的图片!');
return;
}
var promises = this.images.map(function(imageInfo) {
return self.downloadImage(imageInfo).then(function(result) {
self.results.push(result);
// 调用进度回调
if (self.options.onProgress) {
self.options.onProgress(result, self.results.length, total);
}
});
});
Promise.all(promises).then(function() {
// 生成ZIP文件
self.zip.generateAsync({type: 'blob'}).then(function(content) {
saveAs(content, self.options.zipFileName);
// 调用完成回调
if (self.options.onComplete) {
self.options.onComplete(self.results);
}
});
});
},
/**
* 获取文件扩展名
*/
getExtensionFromMime: function(mime) {
var map = {
'image/jpeg': '.jpg',
'image/png': '.png',
'image/gif': '.gif',
'image/webp': '.webp',
'image/svg+xml': '.svg',
'image/bmp': '.bmp',
'image/x-icon': '.ico'
};
return map[mime] || '.jpg';
}
};
使用方式
// 基础使用
var downloader = new ImageDownloader();
downloader.init().downloadAll();
// 自定义配置
var downloader = new ImageDownloader({
selector: '.gallery img', // 只下载画廊中的图片
zipFileName: 'gallery.zip', // 自定义文件名
timeout: 60000, // 超时60秒
maxSize: 5 * 1024 * 1024, // 最大5MB
filter: function(imgEl, url) {
// 自定义过滤:只下载大于100KB的图片
return imgEl.naturalWidth > 500;
},
onProgress: function(result, current, total) {
console.log('进度: ' + current + '/' + total);
},
onComplete: function(results) {
var successCount = results.filter(function(r) { return r.success; }).length;
console.log('下载完成!成功: ' + successCount + '/' + results.length);
}
});
downloader.init().downloadAll();
现代浏览器方案:使用fetch API
如果你的项目需要支持现代浏览器,可以使用更简洁的fetch API替代XMLHttpRequest:
/**
* 使用fetch API下载图片并打包
*/
async function downloadImagesWithFetch() {
var images = document.querySelectorAll('img');
var zip = new JSZip();
var downloadTasks = Array.from(images).map(async function(img, index) {
try {
var response = await fetch(img.src);
var blob = await response.blob();
var extension = getExtensionFromMime(blob.type);
zip.file(`image_${index + 1}${extension}`, blob);
return { success: true, index: index };
} catch (error) {
console.error('下载失败:', img.src, error);
return { success: false, index: index, error: error };
}
});
await Promise.all(downloadTasks);
var content = await zip.generateAsync({ type: 'blob' });
saveAs(content, 'images.zip');
}
// 执行下载
downloadImagesWithFetch();
注意事项
- 跨域问题:由于浏览器的同源策略限制,如果图片来自不同的域名,需要服务器设置CORS头允许跨域访问
- 大文件处理:下载大量或大尺寸图片时,注意控制并发数量和内存使用
- 图片格式:代码中需要根据实际的Content-Type来设置正确的文件扩展名
- 性能优化:对于大量图片,可以考虑使用Web Worker在后台处理打包操作
- 用户体验:建议添加进度条显示,让用户了解打包下载的进度
总结
通过结合JSZip和FileSaver.js两个强大的JavaScript库,我们可以很方便地实现HTML页面图片的打包下载功能。上述代码提供了从基础到增强的多种实现方式,你可以根据实际需求选择合适的方案。需要注意的是跨域问题和性能优化,确保在各种场景下都能稳定运行。
</body> </html>
发表评论 取消回复