以html的视角探寻前端如何跨域批量下载图片

微信公众号上如果想批量的下载图片,右键一一保存十分的繁琐且可能有的图并不提供下载

如果新增一个html文件解析获取所有的图片url路径后下载,很明显会出现跨域报错。因此本文以html的角度给出了详细实现步骤,快速实现批量下载指定页面的图片。

1.阻止Referrer信息发送

事实上,如果是微信公众号中的网页,直接下载或引用资源第一个错误不是跨域,而是为了防止其他平台引入,微信会对请求头 Referer 字段会白名单校验的报错如下

所以在html头部需要加上,阻止发送Referrer信息

<meta name="referrer" content="never">

2. 注意更改浏览器下载位置

3.跨域处理

因为本地直接下载会出现跨域问题,因此需要为发出的请求配置反向代理

  1. nginx安装:官网下载地址
  2. nginx目录下的html目录新增download.html文件(见下文)
  3. nginx.conf(如图)
  4. 双击nginx.exe启动
 server {
    listen       8000;	
    location /wxProxy1/ {
           # 图片所在页面地址
           proxy_pass  https://mp.weixin.qq.com/;
    }
	location /wxProxy2/ {
       	   # 图片路径地址
    	   proxy_pass  https://mmbiz.qpic.cn/;
	}
}

4. download.html

需要修改逻辑的地方

  1. 页面服务器地址,图片路径服务器地址
  2. 正则表达匹配图片标签
  3. 跨域请求前替换服务器地址为nginx反向代理的前缀
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="referrer" content="never">
    <title>图片批量下载</title>
</head>

<body>
    <div id="app">111</div>
    <script>
        Main();
        function Main() {
            // 1.获取页面内容
            // 2.解析获取图片src
            // 3.下载
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if (this.readyState === 4 && this.status === 200) {
                    let htmlString = this.responseText;
                    // 以下解析页面图片标签获取src
                    var regex = /<img class="[^>]*>/g; 
                    var imgTags = htmlString.match(regex);
                    const arr = [];
                    if (imgTags) {
                        var srcRegex = /src="(.*?)"/; 
                        imgTags.forEach(function (tag) {
                            var src = tag.match(srcRegex);
                            if (src && src[1].startsWith("https:") && src[1].endsWith("=webp")) {
                                arr.push(src[1]); 
                            }
                        });
                    }
                    for (let i = 0; i < 1; i++) {
                        setTimeout(() => {
                            downloadImgByXHR(arr[i].replace("https://mmbiz.qpic.cn", "/wxProxy2"), "抹茶蛋蛋" + (i + 1))
                        }, (Math.random() + 1) * 100);
                    }
                }
            };
            xhr.open("GET", "/wxProxy1/s/oQ_Teomrpln7vfRDvFRkUw", true);
            xhr.send();
        } 
        // 下载方式1,使用a标签
        function downloadImgByUrl(url, fileName) {
            // 创建a标签
            var link = document.createElement('a');
            // 设置a标签为不可见
            link.style.display = 'none';
            // 将a标签添加到body
            document.body.appendChild(link);
            // 设置a标签的href
            link.href = url;
            // 设置a标签的download
            link.download = fileName;
            // 模拟点击事件进行下载
            link.click();
            // 下载完成后移除a标签
            document.body.removeChild(link);
        }
        // 下载方式2,XHR请求
        function downloadImgByXHR(url, fileName) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);

            xhr.responseType = 'blob';

            xhr.onload = function () {
                if (this.status === 200) {
                    // 下载文件操作
                    var link = document.createElement('a');
                    var blob = new Blob([this.response], { type: 'image/gif' }); //生成blob对象
                    link.style.display = 'none';
                    link.href = URL.createObjectURL(blob);
                    link.setAttribute('download', fileName); //下载的文件名以及文件格式
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                }
            };

            xhr.onerror = function () {
                console.error('Error downloading the image');
            };

            xhr.send();
        }
        // 图片下载方式2,如果环境有axios
        function downloadImgByAxios(url, fileName) {
            axios({
                url: url,
                method: 'get',
                responseType: 'blob'
            })
                .then(res => {
                    // 下载文件操作
                    const link = document.createElement('a')
                    let blob = new Blob([res.data], { type: 'image/gif' }) //生成blob对象
                    link.style.display = 'none'
                    link.href = URL.createObjectURL(blob)
                    link.setAttribute('download', fileName) //下载的文件名以及文件格式
                    document.body.appendChild(link)
                    link.click()
                    document.body.removeChild(link)
                })
        }
    </script>
</body>

</html>

5.执行代码

访问 localhost:8000/download.html

6.其他环境

  • 在Vue项目环境中也可以实现,原理一样

public/index.html增加meta

vue.conf.js中配置跨域

  • 而python环境中使用requests和Beautifulsoup库可轻松实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝追雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值