起因:课堂派上面的复习题库老师设置了不能下载,直接用电脑对着网页看十分不方便,也不利于做笔记。就想着能不能找点漏洞下载图片转成Pdf方便复习使用。
赶时间的同学可以不用看我前面啰嗦,直接从第二部分下载图片方案
开始即可
通过本次案例,你可以了解:
- 如何使用a标签中的download属性进行图片下载
- 如何处理跨域下载时图片只能预览,不能下载的情况
- 怎么将跨域图片的url变成同源的url以及什么情况下会失效
试着分析一下
网页结构如图所示,word文档是在Modal框里面,是用一张张图片进行展示的,并使用了虚拟列表,只有当图片出现在可视区中才会进行加载
本能的想法: 看浏览器能不能直接通过链接访问图片,可以的话就获取所有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)
下载图片方案
< a href=" " download >下载</ a>
使用Html5中a标签的download属性,点击a标签之后就可以下载了,参考这篇文章:
但是实际使用过程中发现,当我们创建了a
标签之后,跨域资源是不能进行下载的,也是只能进行预览
<a href="https://www.ketangpai.com/images/common/logo_blue.png" download="a7995a"> 不可以跨域下载的链接,只能预览 </a>
解决方案
- 通过图片的url地址请求获得图片的Blob(二进制大对象)数据
- 通过URL.createObjectURL(fileBlob)将Blob转成同源的url图片地址
- 创建
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) } }
第二步,将Blob转化为同源的url
const fileUrl = URL.createObjectURL(fileBlob) console.log(fileUrl)
现在它们就是同源的了,可以通过a
标签的download属性进行下载
其实更准确的来说,这里不是转成url地址,是添加了一个映射,blob在内存中
第三步,创建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>
页面加载完毕后就会自动下载掘金的这张图片
问题
虽然有些图片可以通过上述方式进行图片下载,但是有些图片在进行ajax数据请求得到Blob时,会产生跨域的错误,无法获得Blob,这可能就需要后端的设置了