前端复制粘贴方式上传图片

最近在做一个论坛的项目,发布评论的时候,很多时候会用到截图上传的功能,通过微信截图,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对象上传

前端复制粘贴方式上传图片_第1张图片

//微信截图上传图片时触发
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){
		//将文件读取为 DataURL
		reader.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。

你可能感兴趣的:(前端,vue.js,javascript)