前端复制粘贴方式上传图片
创始人
2024-03-29 15:25:51
0

最近在做一个论坛的项目,发布评论的时候,很多时候会用到截图上传的功能,通过微信截图,QQ截图,直接将截取的图片通过Ctrl+v 复制到输入框里,自动上传将图片渲染到页面上,今天就来实现一个这样的功能。

主要的知识点是,浏览的paste事件,clipboardData

paste 一个标准的Dom事件,粘贴事件,会在用户按下Ctrl+v ,或者通过鼠标复制时触发.像其他事件一样,我们可以通过addEventListener为一个Element添加一个粘贴事件的监听函数 如以下代码。

document.addEventListener('paste', (event) => {console.log('粘贴事件', event)
});
复制代码

Copy

第一步,实现图片粘贴到输入框

我使用vue,给多行输入框绑定一个v-paster的自定义指令,这个自定义指令直接监听元素的粘贴事件。

复制代码

Copy

// 指令粘贴指令定义directives: {paste: {bind(el, binding, vnode) {el.addEventListener('paste', function (event) {//这里直接监听元素的粘贴事件binding.value(event);});},},},
复制代码

Copy

第二步,通过监听paste事件获取文件数据,实现粘贴即上传

paste 一个标准的Dom事件,粘贴事件,会在用户按下Ctrl+v ,或者通过鼠标复制时触发.像其他事件一样,在下面的代码中我打印的是一个叫做ClipboardEvent的对象,内部存在着一个叫做clipboardData的属性,这便是我们在复制时存储数据的对象。 其中的items就是我们要操作的对象,需要粘贴的元素都在其中存储。

然后调用FileReader对象,该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8。这个方法非常容易理解,将文件以文本方式读取,读取的结果即是这个文本文件中的内容。
**readAsBinaryString:**该方法将文件读取为二进制字符串,通常我们将它传送到后端,后端可以通过这段字符串存储文件。
**readAsDataURL:**这是例子程序中用到的方法,该方法将文件读取为一段以 data: 开头的字符串,这段字符串的实质就是 Data URL,Data URL是一种将小文件直接嵌入文档的方案。这里的小文件通常是指图像与 html 等格式的文件。

最后组装为一个formData对象上传

//微信截图上传图片时触发
handleParse(e) {let file = null;var data=e.clipboardData||window.clipboardData, that = this;console.log('fun',data);blob=data.items[0].getAsFile();var isImg=(blob&&1)||-1;var reader=new FileReader();if(isImg>=0){//将文件读取为 DataURLreader.readAsDataURL(blob);}reader.onload=function(event){//获取base64流var base64_str=event.target.result;//div中的img标签src属性赋值,可以直接展示图片// console.log('base64_str',base64_str);var bytes = window.atob(base64_str.split(',')[1]);var array = [];for(var i = 0; i < bytes.length; i++){array.push(bytes.charCodeAt(i));}var blob = new Blob([new Uint8Array(array)], {type: 'image/jpeg'});var formData = new FormData();formData.append('file',blob, Date.now() + '.jpg');formData.append('filename', 'file')console.log(blob);that.update(formData);}
},
update(formData) {// 上传fetch('http://xxx/xxx',{method: 'post',headers: {authorization: localStorage.getItem('token')},body: formData}).then(response => response.json()).then(res=>{let pic = res.data.url;})
},
复制代码

Copy

关于fetch上传图片,在上面的示例中其实失败了很久,最后找到的原因是请求头的content-type,我填了application/json和MulitPart/form-data 均不能成功上传,最后去掉这个content-type才上传成功。原因是fetch 作为浏览器自身提供的api,当传入的参数为 formDate 格式时,不可手动设置content-type。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...