美文网首页Front-End
HTML+JS实现浏览器下载图片

HTML+JS实现浏览器下载图片

作者: 我啊翔1314 | 来源:发表于2019-02-15 18:04 被阅读0次

    如果使用a标签指向一个图片的话,你会发现点击链接时它会直接在浏览器中打开图片并显示:

    <a href="http://www.baidu.com/img/baidu_jgylogo3.gif" />
    

    但是这样的话,就存在一个问题,如果我想点击a链接直接下载图片到本地,该怎么实现呢?
    在查阅资料之后,发现a标签有一个download的属性,添加了该属性,a标签将直接下载文件,并根据download属性的值设置下载文件的文件名,不为download属性设置值则文件将以默认文件名下载:

    <!-- 文件名为默认名称 -->
    <a href="./baidu_jgylogo3.gif" download />
    <!-- 文件名为baidu.gif -->
    <a href="./baidu_jgylogo3.gif" download="baidu" />
    <!-- 文件名为baidu.png -->
    <a href="./baidu_jgylogo3.gif" download="baidu.png" />
    

    但是这个办法有一个弊端,它仅支持同源链接下载,非同源链接还是会直接打开图片:

    <!-- 同源链接能下载图片 -->
    <a href="./baidu_jgylogo3.gif" download />
    <!-- 非同源链接download属性会无效,浏览器会直接打开图片 -->
    <a href="http://www.baidu.com/img/baidu_jgylogo3.gif" download />
    

    尝试了将图片转成Base64或者Blob的办法:

    function downloadImgByBlob(url) {
        var img = new Image()
        img.onload = function() {
            var canvas = document.createElement('canvas')
            canvas.width = img.width
            canvas.height = img.height
            var ctx = canvas.getContext('2d')
            // 将img中的内容画到画布上
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
            // 将画布内容转换为Blob
            canvas.toBlob((blob) => {
                // blob转为同源url
                var blobUrl = window.URL.createObjectURL(blob)
                // 创建a链接
                var a = document.createElement('a')
                a.href = blobUrl
                a.download = ''
                // 触发a链接点击事件,浏览器开始下载文件
                a.click()
            })
        }
        img.src = url
        // 必须设置,否则canvas中的内容无法转换为blob
        img.setAttribute('crossOrigin', 'Anonymous')
    }
    
    function downloadImgByBase64(url) {
        var img = new Image()
        img.onload = function() {
            var canvas = document.createElement('canvas')
            canvas.width = img.width
            canvas.height = img.height
            var ctx = canvas.getContext('2d')
            // 将img中的内容画到画布上
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
            // 将画布内容转换为base64
            var base64 = canvas.toDataURL()
            // 创建a链接
            var a = document.createElement('a')
            a.href = base64
            a.download = ''
            // 触发a链接点击事件,浏览器开始下载文件
            a.click()
        }
        img.src = url
        // 必须设置,否则canvas中的内容无法转换为base64
        img.setAttribute('crossOrigin', 'Anonymous')
    }
    

    上述两种方法效果都不太理想。因为这两种方法仅支持生成jpeg和png格式图片。如果是gif图,仅能显示第一帧的内容。
    后来在download.js官网中看到了如下的示例:

    var x=new XMLHttpRequest();
        x.open("GET", "http://danml.com/wave2.gif", true);
        x.responseType = 'blob';
        x.onload=function(e){download(x.response, "dlBinAjax.gif", "image/gif" ); }
        x.send();
    

    该示例的思路是,通过XMLHttpRequest()请求图片链接,然后获取返回的Blob。那结合上面下载图片的方法,就能下载图片了:

    var x=new XMLHttpRequest();
        x.open("GET", "http://danml.com/wave2.gif", true);
        x.responseType = 'blob';
        x.onload=function(e){
            var url = window.URL.createObjectURL(x.response)
            var a = document.createElement('a');
            a.href = url
            a.download = ''
            a.click()
        }
        x.send();
    

    通过这种方法下载图片,gif图也能够显示正常了。
    注意,上述方法能够兼容大部分浏览器,但是不兼容IE浏览器(不支持download属性)。要兼容IE浏览器需要用其他办法。

    相关文章

      网友评论

        本文标题:HTML+JS实现浏览器下载图片

        本文链接:https://www.haomeiwen.com/subject/rvcmeqtx.html