<!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页面中图片的打包下载,主要分为以下几个步骤:

  1. 获取页面中所有图片的URL地址
  2. 使用XMLHttpRequest或fetch API下载每个图片
  3. 使用JSZip库创建ZIP文件并将图片添加进去
  4. 使用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>

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部