H5的新特性-使用a标签,download属性下载图片

简介: H5的新特性-使用a标签,download属性下载图片

起因:课堂派上面的复习题库老师设置了不能下载,直接用电脑对着网页看十分不方便,也不利于做笔记。就想着能不能找点漏洞下载图片转成Pdf方便复习使用。


赶时间的同学可以不用看我前面啰嗦,直接从第二部分下载图片方案开始即可

通过本次案例,你可以了解:


  • 如何使用a标签中的download属性进行图片下载
  • 如何处理跨域下载时图片只能预览,不能下载的情况
  • 怎么将跨域图片的url变成同源的url以及什么情况下会失效


试着分析一下



网页结构如图所示,word文档是在Modal框里面,是用一张张图片进行展示的,并使用了虚拟列表,只有当图片出现在可视区中才会进行加载


image.png

本能的想法: 看浏览器能不能直接通过链接访问图片,可以的话就获取所有img标签中的链接,然后批量下载。 69张图片太多了,谁愿意一个个去找然后点另存为呢!


获取所有的链接



这一步非常的简单,只需要我们将进度条拖到最底端,让所有图片都加载出来,然后通过js脚本获取就可以了


let src = document.getElementsByTagName("img")
let res = [];
for(let i = 0; i < src.length; i++){
    res.push(src[i].currentSrc)
}
console.log(res)

image.png



下载图片方案



< a href=" " download >下载</ a>


使用Html5中a标签的download属性,点击a标签之后就可以下载了,参考这篇文章:

了解HTML/HTML5中的download属性


但是实际使用过程中发现,当我们创建了a标签之后,跨域资源是不能进行下载的,也是只能进行预览


<a href="https://www.ketangpai.com/images/common/logo_blue.png" download="a7995a">
    不可以跨域下载的链接,只能预览
</a>

image.png

解决方案


  1. 通过图片的url地址请求获得图片的Blob(二进制大对象)数据
  2. 通过URL.createObjectURL(fileBlob)将Blob转成同源的url图片地址
  3. 创建a标签并通过download属性下载图片


第一步,获取图片Blob


    function download(link){
        const xhr = new XMLHttpRequest();
        // link是图片的url地址
        xhr.open('GET',link)
        xhr.responseType = 'blob'
        xhr.send()
        xhr.onload = function () {
            const fileBlob = xhr.response;
            // 获取到了图片的Blob数据
            console.log(fileBlob)
        }
    }

image.png


第二步,将Blob转化为同源的url


const fileUrl = URL.createObjectURL(fileBlob)
console.log(fileUrl)

现在它们就是同源的了,可以通过a标签的download属性进行下载

其实更准确的来说,这里不是转成url地址,是添加了一个映射,blob在内存中


image.png

第三步,创建a标签


const ele = document.createElement('a')
ele.setAttribute('href',fileUrl)
ele.setAttribute('download',"")
ele.click()
ele.innerHTML = '下载'
document.body.appendChild(ele)


完整代码


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    function download(link){
        const xhr = new XMLHttpRequest();
        xhr.open('GET',link)
        xhr.responseType = 'blob'
        xhr.send()
        xhr.onload = function () {
            const fileBlob = xhr.response;
            console.log(fileBlob)
            const fileUrl = URL.createObjectURL(fileBlob)
            console.log(fileUrl)
            const ele = document.createElement('a')
            ele.setAttribute('href',fileUrl)
            ele.setAttribute('download',"")
            ele.click()
            ele.innerHTML = '下载'
            document.body.appendChild(ele)
        }
    }
    download("https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bb72413461364175af5edf2a1fae4446~tplv-k3u1fbpfcp-no-mark:240:240:240:160.awebp?" )
</script>
<a href="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bb72413461364175af5edf2a1fae4446~tplv-k3u1fbpfcp-no-mark:240:240:240:160.awebp?" download="">可以跨域下载的链接</a>
<a href="https://www.ketangpai.com/images/common/logo_blue.png" download="a7995ad.svg">不可以跨域下载的链接,只能预览</a>
</body>
</html>

页面加载完毕后就会自动下载掘金的这张图片


image.png


问题


虽然有些图片可以通过上述方式进行图片下载,但是有些图片在进行ajax数据请求得到Blob时,会产生跨域的错误,无法获得Blob,这可能就需要后端的设置了


image.png


目录
相关文章
|
10月前
|
供应链 Python
如何开发ERP系统中的采购管理板块(附架构图+流程图+代码参考)
本文介绍如何在ERP系统中开发高效采购管理模块,涵盖采购申请、订单处理、入库与退货等关键流程,解析核心功能与业务逻辑,并提供代码参考及开发技巧,助力企业优化采购管理效率。
|
算法
数据结构之卫星通信网络(BFS)
本文介绍了卫星通信网络及其重要性,并探讨了广度优先搜索(BFS)算法在其中的应用。卫星通信网络通过在轨卫星提供全球覆盖的通信服务,尤其在偏远地区和紧急救援中发挥关键作用。BFS算法用于网络拓扑分析、路径规划和故障排除,确保通信网络的高效运行。文章还包括BFS算法的工作原理、特点、优缺点及其实现代码示例。
532 1
|
JSON 前端开发 Go
前端文件下载的方式
【10月更文挑战第5天】
672 58
请问下钉钉有能够获取到群聊天和个人聊天历史记录的api嘛?
DingTalk API 文档中的“消息列表创建”链接似乎已失效:https://developers.dingtalk.com/document/app/message-list-creation. 请注意检查更新或寻找替代资源。
|
前端开发
【若依】 若依内置富文本框quill,editor居中无效
【若依】 若依内置富文本框quill,editor居中无效
2692 0
|
数据采集 安全 调度
【C 言专栏】C 语言与操作系统的交互
【5月更文挑战第1天】C语言在操作系统中扮演核心角色,常用于内核及系统级应用开发。它涉及进程管理(如`fork()`创建进程)、内存分配(`malloc()`、`free()`)、文件操作(`open()`、`read()`等)和设备驱动。C语言允许直接硬件交互,支持进程间通信和文件系统管理,但也带来资源管理、错误处理和可移植性的挑战。在嵌入式系统中,C语言尤为重要。随着技术发展,C语言将继续适应新操作系统和硬件架构,与其他语言融合,推进系统编程进步。
493 0
【C 言专栏】C 语言与操作系统的交互
|
JavaScript 索引
vue element plus 自动补全输入框
vue element plus 自动补全输入框
688 0
|
Web App开发 开发框架 前端开发
SpringCloud微服务实战——搭建企业级开发框架(三十九):使用Redis分布式锁(Redisson)+自定义注解+AOP实现微服务重复请求控制
通常我们可以在前端通过防抖和节流来解决短时间内请求重复提交的问题,如果因网络问题、Nginx重试机制、微服务Feign重试机制或者用户故意绕过前端防抖和节流设置,直接频繁发起请求,都会导致系统防重请求失败,甚至导致后台产生多条重复记录,此时我们需要考虑在后台增加防重设置。
927 53
SpringCloud微服务实战——搭建企业级开发框架(三十九):使用Redis分布式锁(Redisson)+自定义注解+AOP实现微服务重复请求控制