uniapp项目使用html2canvas在h5端生成海报并下载

文章讲述了在h5商城中实现商品海报分享功能时遇到的跨域问题,主要涉及前端使用xhr请求图片时的CORS限制。通过下载图片转base64、uni-app的特性分析,以及与阿里云OSS的CORS配置,作者解决了图片加载问题并找到了正确的配置方式。
摘要由CSDN通过智能技术生成


前言

需求是在h5商城增加商品海报分享功能,海报包含商品活动信息,商品本身信息。


一、问题表现

在保存海报之后,部分手机可显示图片,部分商品可正常显示图片

二、定位问题及解决问题过程中使用的方法

1.纯前端

控制台报因为cors策略图片跨域的错误,在网上找到了关于前端图片跨域解决的办法

方法1将跨域图片下载下来转换为base 64格式存在本地,然后转换路径,将需要展示的dom元素原本的网络路径改为本地存贮路径,以下是代码

async getBase64(imgUrl) {
      return new Promise((reslove, reject) => {
        try {
          let xhr = new XMLHttpRequest();
          xhr.open("get", imgUrl, true);
          // 重点1
          xhr.responseType = "blob";
          xhr.onload = function () {
            console.log("请求完成时触发", this);
            if (this.status == 200) {
              //得到一个blob对象
              let blob = this.response;
              // 重点2
              let oFileReader = new FileReader();
              oFileReader.onloadend = function (e) {
                // 结果
                const base64 = e.target.result;
                document.getElementById("imgUrlId").children[1].src = base64;
                // console.log('查看所有子节点',document.getElementById("imgUrlId").children)
                //将网络路径转换为本地图片路径
                document.getElementById(
                  "imgUrlId"
                ).children[0].style.backgroundImage = `url(${base64})`;
                reslove(true);
              };
              oFileReader.readAsDataURL(blob);
            } else {
              console.log("getbase64", this);
            }
          };
          xhr.onreadystatechange = function () {
            console.log("xhr.readyState值改变触发", xhr.readyState);
          };
          xhr.onloadstart = function () {
            console.log("调用send后立即触发", xhr);
          };
          xhr.onloadend = function () {
            console.log("请求结束(成功或失败触发)", xhr.readyState);
          };
          xhr.onerror = function (err) {
            console.log(
              "出现错误",
              err,
              "xhr.statusText",
              xhr.statusText,
              "xhr.readyState",
              xhr.readyState
            );
          };
          xhr.send();
        } catch (e) {
          console.log("查看抛出异常", e);
        }
      });
    },

但是发现个很坑的事情,本身这个域名请求网络图片地址就报错跨域了,用原生的xhr请求不是一样的也会报跨域,这点在pc端启动项目是不会体现错误的,后面一发布到h5端运行就展示不出图片,找了一会,发现两个错误,一个是报错图片跨域,这个好理解,如下图:

这个是因为uni-app的image标签不是一个单纯的dom元素,是一个服务器控件,经过编译后会

变成多层标签嵌套,如下图:

会变成一个含有背景图片的div包裹着img,显示的也是div。

然后紧接着在网络请求中发现了另外一个奇怪的错误,如下图:

后面查阅了资料,更加确定是跨域问题

请求状态码为0的几种可能(如有补充,欢迎留言):

1.xhr请求的路径有误

2.网络问题

3.检查防火墙拦截

4.请求跨域

然后在配置跨域的时候,cors同源策略需要后端配合,但问了我这边的后端大牛,项目是直接请求阿里云的oss静态资源托管,没有走后端自己的接口,本来挺苦恼的,转念一想,既然直接走的oss,又报错cors,是不是阿里云原本就有关于cors的配置项?

2.通过修改oss配置

后面登录oss控制台,果然查询到有关于cors的配置项(注意:配置后需要过一段时间生效)

一般来说配成这样就可以,这个表示允许所有来源访问,如果希望指定来源访问的话前端需要在请求的时候带上请求头,和配置保持一致,再一个就是暴露Headers里的需要配置,里面的Etag表示访问失败的抛出错误信息。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值