• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

前端通过http获取图片流并转存

武飞扬头像
Nic_LittleCow
帮助3

一.场景

        昨天公司里面提了一个需求,将竞争对手的sku通过一些手段导入我们自己的数据库,普通数据比较好搞,但是图片这种静态资源我们只能获取到一个url,所以需要进行一次转存。

二.实现

        这里有两个思路,一个是交给后端来做这个事情,但是后端做的话,会暴露我们自己的后端,给对手留下痕迹。第二个就是前端来做,每次使用不同的电脑访问网站来做这个数据转存的操作就给追踪提高难度,因为对方也不知道我们是否是正常的访问资源。

        最终选择了前端来做。第一步,通过http获取到该网站的数据,模拟登录获取token,截取下来他的商品列表数据。这个就不贴代码了,也可以通过不使用代码的方式来实现。

        第二步。将获取到的商品数据里面的图片读取出来并上传

  1.  
    /**
  2.  
    * @descrip 将blob对象转换成file对象
  3.  
    * @param {Blob} blob 需要转换成文件的blob对象
  4.  
    * @param {string} fileName 文件名
  5.  
    * @param {string} fileType 文件类型
  6.  
    * @return {Promise} 返回一个promise对象,即处理之后的文件对象
  7.  
    **/
  8.  
    const transToFile = async(blob, fileName, fileType) => {
  9.  
    return new window.File([blob], fileName, { type: fileType })
  10.  
    }
  11.  
     
  12.  
    /**
  13.  
    * @descrip 将互联网上面的图片读取成buffer并且转存至私有的服务器
  14.  
    * @param {string} url 需要转换成的图片的公网地址 eg:https://image.xxx.com/uploads/image/product/62b2babba1c9c_thumb.jpg
  15.  
    * @return {Promise} 返回一个promise对象,即上传成功之后的图片url
  16.  
    **/
  17.  
    const getFileStreamAndUpload = async (url) => {
  18.  
    return new Promise((resolve, reject) => {
  19.  
    let suffix = "jpg"
  20.  
    let fileNameArr = url.split("/")
  21.  
    let fileName = fileNameArr[fileNameArr.length - 1]
  22.  
    if (url.split(".").length > 1) {
  23.  
    suffix = url.split(".")[1]
  24.  
    }
  25.  
    // 通过axios读取图片时一定要加上这个responseType,不然是乱码
  26.  
    axios.get(url, {responseType: 'arraybuffer'}).then(async res => {
  27.  
    // 构建blob对象
  28.  
    const blob = new Blob([res.data], { type: `image/${suffix};charset=utf-8` })
  29.  
    let getFile = transToFile(blob, fileName, `image/${suffix}`)
  30.  
    getFile.then(async res1 => {
  31.  
    // 通过FormData将文件提交给后端
  32.  
    let formData = new FormData()
  33.  
    formData.append('file', res1)
  34.  
    formData.append('folderName', "fsImage")
  35.  
    let res2 = await bar.uploadFile(formData)
  36.  
    if (res2.code == 200) {
  37.  
    resolve(res2.data)
  38.  
    } else {
  39.  
    reject(new Error("图片上传失败"))
  40.  
    }
  41.  
    })
  42.  
    })
  43.  
    })
  44.  
    }
学新通
  1.  
    // 获取数据成功之后
  2.  
    const loadingInstance = ElLoading.service({ fullscreen: true })
  3.  
    // 这里的res.data.data 就是竞争对手的商品列表数据
  4.  
    let fsData = res.data.data
  5.  
    for (let i = 0; i < fsData.length; i ) {
  6.  
    const item = fsData[i];
  7.  
    // 这里可能会出现跨域请求资源的情况所以使用代理将真实的域名代理到本地的开发服务器上面
  8.  
    item.productUrl = await getFileStreamAndUpload(item.thumb_path.replace("https://image.xxx.com", "/fsimgapi"))
  9.  
    }
  10.  
    console.log(fsData);
  11.  
    loadingInstance.close()
  12.  
    ElMessage.success("数据转移成功")

 效果图,这里转换完成之后就直接输出了一个转换后的数组出来,后续根据业务需求将这个数组提交给后端即可。

 学新通

 学新通

三.总结 

其实这种功能最好还是由后端或者nodejs来做,纯前端不可避免的会遇到跨域问题。主要的技术要点就是将网络上面的静态资源通过读取成流的形式放在浏览器缓存里面,然后利用Blob对象跟File对象之间的互相转换,就可以得到一个个的文件对象了,最后通过FormData将数据上传即可。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhekfcfb
系列文章
更多 icon
同类精品
更多 icon
继续加载