【首发】JS将图片转化为base64编码,并实现点击下载,js实现图片下载的实操博客

举报
梦想橡皮擦 发表于 2022/02/19 10:42:34 2022/02/19
【摘要】 背景需求在前端的工作中,经常碰到点击下载图片的需求,但是有一种情况大家经常碰到,就是点击下载地址之后,在浏览器窗口默认打开了,并没有调用浏览器进行下载如果你正在完善这个需求,一直解决不了,恭喜你看到了这篇文章。在正式开始前,先说一下整体的逻辑JS实现下载图片非常简单,网上有很多的分享将图片转换为base64为了防止大图下载失败,将base64转换为 blob;下载图片。 编码时间整体逻辑代...

背景需求

在前端的工作中,经常碰到点击下载图片的需求,但是有一种情况大家经常碰到,就是点击下载地址之后,在浏览器窗口默认打开了,并没有调用浏览器进行下载

如果你正在完善这个需求,一直解决不了,恭喜你看到了这篇文章。

在正式开始前,先说一下整体的逻辑
JS实现下载图片非常简单,网上有很多的分享

  1. 将图片转换为base64
  2. 为了防止大图下载失败,将base64转换为 blob;
  3. 下载图片。

编码时间

整体逻辑代码如下所示

<!DOCTYPE html>
<html lang="en">
<head>
    <title>图片点击下载</title>
</head>

<body>
    <button onclick="download_iamge('https://某地址图片','测试')">点击下载图片</button>
     
    <script>
        function download_iamge(imgsrc,name) {
         
            var image = new Image(); // 声明图片对象
            image.setAttribute('crossOrigin', 'Anonymous'); // 解决跨域 Canvas 污染问题
             // 图片加载完毕,获取 base64 并转换为 blob 格式
            image.onload = function () {
                var canvas = document.createElement('canvas');
                canvas.width = image.width;
                canvas.height = image.height;
                var context = canvas.getContext('2d');
                context.drawImage(image, 0, 0, image.width, image.height);
                var data_base64 = canvas.toDataURL('image/png'); //得到图片的base64编码数据

                var blob_ = data_to_blob(data_base64); // 转换为 blob

                var url = {
                    name: name,
                    src: blob_
                };

                if (window.navigator.msSaveOrOpenBlob) {   
                    navigator.msSaveBlob(url.src, url.name);
                } else {
                    var link = document.createElement("a");
                    link.setAttribute("href", window.URL.createObjectURL(url.src));
                    link.setAttribute("download", url.name + '.png');
                    document.body.appendChild(link);
                    link.click();
                }
            };
            image.src = imgsrc;
            // base64 转换为 blob 
            function data_to_blob(data_base64) {
                var arr = data_base64.split(','), mime = arr[0].match(/:(.*?);/)[1],
                    bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n);
                }
                return new Blob([u8arr], {type: mime});
            }
        }

       
    </script>
    
</body>

</html>

答题时间

很多教程到此就结束了,但是并没有说明以下几个问题

'crossOrigin', 'Anonymous':canvas 跨域问题

如果没有该内容将会出现错误内容:canvas无法执行toDataURL方法,即污染的画布无法输出,但是这里其实还存在一个问题,就是如果你使用的是 cdn 加速的静态图片,那还是无法跨域,解决的亮点在于配置 CDN HTTP头配置跨域资源共享(CORS),从而解决该问题,如果你没有运维权限,可以联系运维工程师,在CDN后台参考下述配置。

一定让 CDN 的响应头包含如下配置 Access-Control-Allow-Origin:*,当然仅开启某些域名跨域访问也是可以的,看需求。

如果你使用的不是CDN,而是其它服务器,但服务和资源不在一个域名下
以下内容使用 Nginx 进行介绍。
在静态资源服务器配置如下内容。

location ^~ /静态资源文件夹/ {
  alias /www/wwwroot/静态资源文件夹/;
  # 开启允许跨域访问
  add_header 'Access-Control-Allow-Origin' '*';
}

我想,到这里你已经能完成 js 实现图片下载 这一操作了

这里还会衍生出一个面试问题,你知道 canvas 污染么?

记录时间

2022年度 Flag,写作的 563 / 1024 篇。
可以关注我,点赞我、评论我、收藏我啦。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。