JavaScript实现将图片地址转成文件流并上传

 更新时间:2024年04月23日 11:45:08   作者:橙某人  
这篇文章主要为大家详细介绍了如何使用JavaScript实现将图片地址转成文件流并上传,感兴趣的小伙伴可以跟随小编一起学习一下

写在开头

最近,小编在业务中遇到一个图片转存的场景。

领导:大概过程就是,接口会给我返回一个图片列表数据,图片路径是全路径,但是路径中的域名是其他系统的,必须要在用户选择图片的时候将图片重新转存到自个的系统上,防止其他系统删除图片对此有影响。

我:Em...很合理的需求。

(但是,和有什么关系?我只是一个前端小菜鸡呀,不祥的预感.......)

我:(卑微提问)这个过程不是放后端做比较合理一点?

后端大哥:前端不能做?

我:可以可以,只是...这个好像会跨域?

后端大哥:已经配置了请求头('Access-Control-Allow-Origin': '*')。

我:哦,好的,我去弄一下。(*******此处省略几万字心理活动内容)

第一种(推荐)

那么,迫于......不,我自愿的,我们来看看前端要如何完成这个转成过程,代码比较简单,直接贴上来瞧瞧:

async function imageToStorage(path) {
  // 获取文件名
  const startIndex = path.lastIndexOf('/');
  const endIndex = path.indexOf('?');
  const imgName = path.substring(startIndex + 1, endIndex);
  // 获取图片的文件流对象
  const file = await getImgToFile(path, imgName);
  // TODO: 将File对象上传到其他接口中
}

/**
 * @name 通过fetch请求文件,将文件转成文件流对象
 * @param { string } path 文件路径全路径
 * @param { string } fileName 文件名
 * @returns { File | undefined }
 */
function getImgToFile(path, fileName) {
  const response = await fetch(path);
  if (response) {
    const blob = await response.blob();
    const file = new File([blob], fileName, { type: blob.type });
    return file;
  }
}

上述方式,在后端配置了允许跨域后,正常是没有什么问题的,也是比较好的一种方式了。

但是,在小编实际第一次编码测试后,却还是遇上了跨域。

一猜应该就是后端实际还没配置好,问了一下。

后端大哥:还没部署,一会再自己试试。

我:嗯嗯。

第二种

等待的过程,小编又在网上找了找了,找到了第二种方式,各位看官可以瞧瞧:

/** @name 将图片的网络链接转成base64 **/
function imageUrlToBase64(imageUrl: string, fileName: string): Promise<File> {
    return new Promise(resolve => {
      const image = new Image();
      // 让Image元素启用cors来处理跨源请求
      image.setAttribute('crossOrigin', 'anonymous'); 
      image.src = imageUrl + '&v=' + Math.random();
      image.onload = () => {
        const canvas = document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        const context = canvas.getContext('2d')!;
        context.drawImage(image, 0, 0, image.width, image.height);
        // canvas.toDataURL
        const imageBase64 = canvas.toDataURL('image/jpeg', 1); // 第二个参数是压缩质量
        // 将图片的base64转成文件流
        const file = base64ToFile(imageBase64, fileName);
        resolve(file);
      };
    });
  }
  /** @name 将图片的base64转成文件流 **/
function base64ToFile(base64: string, fileName: string) {
    const baseArray = base64.split(',');
    // 获取类型与后缀名
    const mime = baseArray[0].match(/:(.*?);/)![1];
    const suffix = mime.split('/')[1];
    // 转换数据
    const bstr = atob(baseArray[1]);
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    // 生成文件流
    const file = new File([u8arr], `${fileName}.${suffix}`, {
      type: mime,
    });
    return file;
}

这第二种方式由于要先把图片绘制到 canvas 再去转成 base64 再去转成文件流,小编用 console.time 稍微测了一下,每次转化过程都要几百毫秒,图片越大时间越长,挺影响性能的。

所以,小编还是推荐使用第一种方式,当然,最稳妥的方案是后端去搞最好了。

网上很多都说第二种方式可以直接绕过跨域,各种谈论。

主要就是这个 crossOrigin 属性。MDN解释

它原理是通过了 CORS

或者可以再看看这个解释:传送门

到此这篇关于JavaScript实现将图片地址转成文件流并上传的文章就介绍到这了,更多相关JavaScript图片地址转文件流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript数据结构链表知识详解

    JavaScript数据结构链表知识详解

    存储有序的元素集合,但不同于数组,链表中的元素在内存中不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。下面通过本文给大家详细介绍下,需要的朋友参考下
    2016-11-11
  • 探索Emberjs制作一个简单的Todo应用

    探索Emberjs制作一个简单的Todo应用

    使用Emberjs制作一个简单的Todo应用,需要的朋友可以参考下
    2012-11-11
  • js防止表单重复提交的两种方法

    js防止表单重复提交的两种方法

    第一种:用flag标识,下面的代码设置checkSubmitFlg标志;第二种:在onsubmit事件中设置,在第一次提交后使提交按钮失效,感兴趣的朋友可以了解下
    2013-09-09
  • electron中的IPC通信及性能进阶技巧

    electron中的IPC通信及性能进阶技巧

    本文详解Electron IPC的四种通信模式、安全实践(上下文隔离、禁用Node.js集成)及性能优化(数据传输、减少调用),并指出事件监听泄漏、数据序列化限制等常见陷阱,感兴趣的朋友一起看看吧
    2025-07-07
  • JS实现点击图片在当前页面放大并可关闭的漂亮效果

    JS实现点击图片在当前页面放大并可关闭的漂亮效果

    点击图片在当前页面放大的漂亮效果实现方法有很多,在本文将为大家介绍下使用Lightbox JS是如何实现的,感兴趣的朋友不要错过
    2013-10-10
  • layui switch 开关监听 弹出确定状态转换的例子

    layui switch 开关监听 弹出确定状态转换的例子

    今天小编就为大家分享一篇layui switch 开关监听 弹出确定状态转换的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 浅析JS中对函数function的理解(基础篇)

    浅析JS中对函数function的理解(基础篇)

    我们知道,在js中,函数实际上是一个对象,每个函数都是Function类型的实例,并且都与其他引用类型一样具有属性和方法。下面给大家谈下对JS中函数function的理解,一起看看吧
    2016-10-10
  • JavaScript中判断页面关闭、页面刷新的实现代码

    JavaScript中判断页面关闭、页面刷新的实现代码

    这篇文章主要介绍了JavaScript中判断页面关闭、页面刷新的实现代码,在一些特殊的场合中会用到这个技术,需要的朋友可以参考下
    2014-08-08
  • bootstrap下拉菜单使用方法解析

    bootstrap下拉菜单使用方法解析

    这篇文章主要为大家详细解析了bootstrap下拉菜单使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • 原生JavaScript实现日历功能代码实例(无引用Jq)

    原生JavaScript实现日历功能代码实例(无引用Jq)

    这篇文章主要介绍了原生JavaScript实现日历功能代码实例(无引用Jq),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09

最新评论