【踩坑记】小程序码下载的二三坑

574 阅读2分钟

前言

本人是一个半路出家刚刚拥有一年前端开发经验的技术菜鸟。实战经验不够丰富,在项目开发过程中踩的坑比较多,故此记录,望自己能踩更多的坑,让他人无坑可踩。

坑一

最近在开发一个web管理后台,需要实现一个小程序码下载的功能。本来以为很简单,因为之前做过文件下载的功能。

按照之前的做法,我们前端只需要将后端返回的小程序码链接赋值给window.location.href就行。

然而,小程序码并没有如愿下载,而是被打开预览了。

这是怎么回事,明明在其他项目中,同样的方法是可以实现文件下载的。

后来一番搜索后才发现,原来:

1、对于rar、doc、excel等浏览器不能打开的文件,使用window.location.href才可以实现下载。

2、而对于浏览器能打开的文件,例如html、xml等,这样去写不是下载,而是打开。

坑二

那么,怎样才能实现小程序码的下载呢?

试了试canvas + <a>这对小组合。

   getUrlBase64( url ) {
      const that = this
      return new Promise( ( resolve, reject ) => {
        let canvas = document.createElement( 'canvas' )
        const ctx = canvas.getContext( '2d' )
        const img = new Image()
        img.src = url
        img.onload = function () {
           canvas.height = 300
           canvas.width = 300
           ctx.drawImage( img, 0, 0, 300, 300 )
           const dataURL = canvas.toDataURL( 'image/png' )
           canvas = null
           resolve( dataURL )
        }
        img.onerror = function ( err ) {
          reject( err )
          that.$message.warning( '小程序码下载失败!' )
        }
      })
    },
    downCode() {
      this.loading = true
      this.getUrlBase64( this.info.codeUrl )
        .then( ( base64 ) => {
          const link = document.createElement( 'a' )
          link.href = base64
          link.download = '职位小程序码'
          link.click()
       } )
        .finally( () => {
          this.loading = false
       } )
    },

然而,报错了!!!

image.png

好吧,图片资源不在同一域名下,跨域了,只好乖乖地加了img.crossOrigin = 'anonymous',这下总行了吧!

坑三

然而,还是报跨域的错,这是为嘛,明明已经加了img.crossOrigin = 'anonymous',允许跨域了啊。

又是一顿折腾。

原来,<img>标签引入小程序码图片的时候,浏览器已经将其缓存起来了。当再通过Image对象对其加载,浏览器自身会监测,发现有缓存但又与当前域名不一致,认为当前是跨域访问。

这里即便是服务端设置允许跨域也没有办法。

那怎么办?

感谢万能的网友,再次给我指明了方向!

在用Image对象加载图片的时候,在src地址后面拼接一个时间戳,绕过缓存。

img.src = url + '&tamp=' + ( new Date() ).valueOf()

至此,踩坑结束,小程序码终于实现了下载!妈呀,真不容易!

=====================2023年4与28日更新=================================

最近又遇到图片跨域问题了。 即使像坑三一样,加上了时间戳,依然报错跨域。联合后端一顿排查,发现居然是阿里云里面没有配置允许跨域(我们项目的图片都存在阿里云上)。 所以,以后再遇到跨域问题,一定要先检查配置啊!