一、问题描述:

下载历史课堂板书原来是需要点图片一张张下载,比较麻烦;调整为把所有图片合并为pdf后下载。应用jsPDF插件,在移动端获取图片地址时,报跨域问题。

ios 图片跨域 图片跨域怎么解决_跨域

二、知识点补充:

1、jsPDF 是一个基于HTML5的客户端解决方案,用于生成各种用途的 PDF 文档。

1、安装:npm install jspdf

2、引入:import jsPDF from "jspdf"

3、使用:

let pdf = new jsPDF('p', 'pt', 'a4');
//第一个参数: l:横向 p:纵向
//第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px")
//第三个参数:默认为“a4”。如果您想使用自己的格式,只需将大小作为数字数组传递,例如[595.28, 841.89];

4、常用方法

pdf.addPage()  在PDF文档中添加新页面:

readPDF.addPage([imgwidth,imgHeight], 'p')//参数:(尺寸大小:默认a4 , 方向l:横向 p:纵向)

pdf.addImage()  将图像添加到PDF:

readPDF.addImage(ImageDate, 'JPEG', posX, posY, imgWidth, imgHeight)//参数:(imageData,格式,开始坐标x,开始坐标y,宽,高)

pdf.save() 保存pdf文档

readPDF.save('板书.pdf')

 

三、问题梳理分析:

图片是来自于阿里云服务器的,跟访问的页面不是同一个域名,存在跨域的问题。这边有两个问题:

1、为什么图片在页面上能正常显示?

通过 dom 节点的 <img> 标签来直接访问是没有问题,因为浏览器本身不会有跨域问题。而图片再次被复用到 canvas 上去时,就报跨域错误。

2、为什么pc端没有问题?

pc端是electron框架内置chrome浏览器,关闭了跨域设置。移动端是通过webview访问,存在跨域问题。

如果是chrome环境,同样存在跨域问题。

 

四、解决方式:

图片增加crossOrigin属性

<img crossOrigin="anonymous"/>

pdf根据图片生成pdf时,创建image标签,给图片也加上crossOrigin属性

const img = new Image();
img.crossOrigin = 'anonymous';

加了 crossorigin 属性,则表明图片就一定会按照 CORS 来请求图片。而通过CORS 请求到的图片可以再次被复用到 canvas 上进行绘制。换言之,如果不加 crossorigin 属性的话,那么图片是不能再次被复用到 canvas 上去的。

什么是crossOrigin?

ios 图片跨域 图片跨域怎么解决_ios 图片跨域_02

 相较于anonymous,use-credentials 是加了证书的 CORS。

 

五、问题后续:

这种方式,可以解决新生成图片的跨域问题。对于用户以前访问过的图片,浏览器默认情况下会将其缓存起来。当我们从 JS 的代码中创建的 <img> 再去访问同一个图片时,浏览器就不会再发起新的请求,而是直接访问缓存的图片。而缓存中的图片是不带跨域头的,所以浏览器直接就拒绝了。

处理方式:

pdf生成图片时,使用时间戳去直接访问服务器资源,绕过访问浏览器缓存;至此问题彻底解决。

const img = new Image();
-      img.src = src;
+      img.src = `${src}?${Date.now()}`;
       img.crossOrigin = 'anonymous';

 

参考:


https://www.jianshu.com/p/8fa0fb53c183