html2canvas 生成 pdf 出现 CORS 问题

html2canvas 生成 pdf 的代码如下:(参考掘金

createPDF(id, name) {
      let demo = document.getElementById(id);
      demo.style.overflow = 'visible';
      html2canvas(demo, {
        useCORS: true, // 跨域
        height: document.getElementById(id).scrollHeight,//
        width: document.getElementById(id).scrollWidth,//为了使横向滚动条的内容全部展示,这里必须指定
        backgroundColor: "#FFFFFF",//如果指定的div没有设置背景色会默认成黑色
      }).then(function (canvas) {
        var contentWidth = canvas.width;
        var contentHeight = canvas.height;
        //一页pdf显示html页面生成的canvas高度;
        var pageHeight = contentWidth / 595.28 * 841.89;
        //未生成pdf的html页面高度
        var leftHeight = contentHeight;
        //pdf页面偏移
        var position = 0;
        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
        var imgWidth = 555.28;
        var imgHeight = 555.28 / contentWidth * contentHeight;
        var pageData = canvas.toDataURL('image/jpeg', 1.0);
        var pdf = new jsPDF('', 'pt', 'a4');
        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
        //当内容未超过pdf一页显示的范围,无需分页
        if (leftHeight < pageHeight) {
          pdf.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight);
        } else {
          while (leftHeight > 0) {
            pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
            leftHeight -= pageHeight;
            position -= 841.89;
            //避免添加空白页
            if (leftHeight > 0) {
              pdf.addPage();
            }
          }
        }
        pdf.save(name + '.pdf');
        demo.style.overflow = 'auto';
      });
    }

发现问题

测试原始元素是这样的:(当点击 print 按钮后,将下面的内容生成 pdf)

当点击 print 按钮后,控制台报错(CORS)

此时,虽然可以生成 pdf,但却无法展示图片内容

解决问题

以在 Debian 10 服务器上的 apache 为例

1. 首先,启用 mod_headers.so 模块

sudo a2enmod headers

2. 然后,可选择在 /etc/apache2/sites-available/xxx.conf 或 网站根目录下 .htacess 文件中设置允许跨域,此处以后者为例:

<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
</IfModule>

3. 重启服务器

sudo systemctl reload apache2

此时,再重新 print,发现依然提示跨域,是由于缓存导致的。

我们可以在 img 标签的 src 属性中,添加动态的参数,例如时间戳 https://xxxx.com/xxx.jpg?t=[时间戳],即可解决缓存问题。

最后,生成的 pdf 效果如下:

发表评论


*