JS 从剪贴板上传图片
用Ubuntu两年多了,习惯了Ubuntu的操作感觉比WIN用起来还爽,就一点不爽,生态应用很少,好多WIN上好用的软件在Ubuntu找不到的,希望以后的软件可以做到一次编译全平台通用. 即使用上Wine有的软件应用也存在兼容性问题.比如QQ,Photoshop,微信,旺旺.
所以,在Ubuntu使用过程中,习惯了用web来访问,凡事web-Application通通喜欢.
微信和钉钉经常用,不喜欢wine安装的应用,就直接网页版微信,网页版钉钉,发现好YI功能,当我截图复制到剪贴板后,可以直接Ctrl+V在网页版微信,钉钉粘贴,不用在把图片先保存在电脑上,再选择发送文件这么复杂.

然后呢,命题就出来了,如何做到从剪贴板获取图片并发送图片呢?
paste剪贴板事件
onpaste 事件在用户向元素中粘贴文本时触发。
有三种方式可以在元素中粘贴内容:
- 按下 CTRL + V
- 从浏览器的编辑菜单中选择 "Paste(粘贴)"
- 右击鼠标按钮在上下文菜单中选择 "Paste(粘贴)" 命令
参考:https://www.w3cschool.cn/jsref/event-onpaste.html
绑定的元素不一定是input,普通的div也是可以绑定的,如果是给document绑定了,就相当于全局了,任何时候的粘贴操作都会触发。
粘贴事件提供了一个clipboardData的属性,如果该属性有items属性,那么就可以查看items中是否有图片类型的数据了。
clipboardData介绍
介绍一下clipboardData对象,它实际上是一个DataTransfer类型的对象,DataTransfer是拖动产生的一个对象,但实际上粘贴事件也是它。
clipboardData的属性介绍
| 属性 | 类型 | 说明 |
|---|---|---|
| dropEffect | String | 默认是 none |
| effectAllowed | String | 默认是 uninitialized |
| files | FileList | 粘贴操作为空List |
| items | DataTransferItemList | 剪切板中的各项数据 |
| types | Array | 剪切板中的数据类型 该属性在Safari下比较混乱 |
items介绍
items是一个DataTransferItemList对象,自然里面都是DataTransferItem类型的数据了。
items属性
items的DataTransferItem有两个属性kind和type
| 属性 | 说明 |
|---|---|
| kind | 一般为string或者file |
| type | 具体的数据类型,例如具体是哪种类型字符串或者哪种类型的文件,即MIME-Type |
items方法
| 方法 | 参数 | 说明 |
|---|---|---|
| getAsFile | 空 | 如果kind是file,可以用该方法获取到文件 |
| getAsString | 回调函数 | 如果kind是string,可以用该方法获取到字符串,字符串需要用回调函数得到,回调函数的第一个参数就是剪切板中的字符串 |
types介绍
一般types中常见的值有
| 值 | 说明 |
|---|---|
| text/plain | 普通字符串 |
| text/html | 带有样式的html |
| Files | 文件(例如剪切板中的数据) |
以上介绍COPY来自: https://www.jb51.net/article/123071.htm
FileReader对象
FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。
事件处理
FileReader.onload处理load事件。该事件在读取操作完成时触发。
FileReader.onloadend处理loadend事件。该事件在读取操作结束时(要么成功,要么失败)触发。
方法
FileReader.readAsDataURL()开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容。
readAsDataURL: 该方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成(DONE),并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
示例: https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsDataURL
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
来自:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
base64数据转blob二进制
请看昨日文章:
JS 实现blob与base64互转
/**
* base64 to blob二进制
*/
function dataURItoBlob(dataURI) {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
var byteString = atob(dataURI.split(',')[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图 for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {type: mimeString});
}
呈上仿制代码
ok,以上需要的事件, FileReader对象操作,base64数据转换都有了,那我们就直接上代码.
ImageClipboard.html
<div id="box"></div>
<script type="text/javascript"> // window.addEventListener('paste', pasteHandler); pasteHandler= fun...
window.addEventListener('paste', function (e) {
var items;
if (e.clipboardData && e.clipboardData.items) {
items = e.clipboardData.items;
if (items) {
items = Array.prototype.filter.call(items, function (element) {
return element.type.indexOf("image") >= 0;
}); Array.prototype.forEach.call(items, function (item) {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onloadend = function (event) {
var imgBase64 = event.target.result; // event.target.result.split(",") [0]=data:image/png;base64 [1]=data
console.log(imgBase64); // base64
var dataURI = imgBase64;
var blob = dataURItoBlob(dataURI); // blob
console.log(blob);
uploadImg(blob); };
reader.readAsDataURL(blob); });
}
}
}); /**
* base64 to blob二进制
*/
function dataURItoBlob(dataURI) {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
var byteString = atob(dataURI.split(',')[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图 for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {type: mimeString});
} /**
* 上传图片 FormData
*/
function uploadImg(file) {
var formData = new FormData();
formData.append('my-image-file', file);
formData.append('username', 'myfile'); // 添加自定义数据 var xhr = new XMLHttpRequest();
xhr.open('POST', '/html/upload-ser.php');
xhr.onload = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var data = JSON.parse(xhr.responseText), tarBox = document.getElementById('box');
if (data.id == 1) {
var img = document.createElement('img');
img.className = 'my_img';
img.src = data.src;
tarBox.appendChild(img); return 'aaa';
} else {
alert(data.msg);
}
} else {
console.log(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.log(xhr.statusText);
}
xhr.send(formData);
}
</script>
服务端upload-ser.php
<?php //print_r($_POST);
//print_r($_FILES); $file = $_FILES['my-image-file'];
if ($file['error'] == 0) {
define('ROOT', __DIR__);
if (is_uploaded_file($file['tmp_name'])) {
$ext = explode('/', $file['type'])[1];
$filename = "{$file['name']}_" . date("ymdHis") . ".{$ext}";
$mu = move_uploaded_file($file["tmp_name"], ROOT . "/upload/" . $filename);
if ($mu) {
exit(json_encode(['id' => 1, 'src' => 'upload/' . $filename]));
} else {
exit(json_encode(['id' => 2, 'msg' => 'move file fail']));
}
} else {
exit(json_encode(['id' => 2, 'msg' => 'failed no post']));
}
} else {
exit(json_encode(['id' => 2, 'msg' => $file['error']]));
}
在页面中,我们直接Ctrl+V后, 可以先通过打印POST和FILES看下数据

username 是自定义的post数据,my-image-file是file数据.
console.log打印:

通过xhr返回callback得到上传后的信息

查看上传的目录

GIF

JS 从剪贴板上传图片的更多相关文章
- ajaxFileUpload.js 无刷新上传图片,支持多个参数同时上传,支持 ie6-ie10
/* 131108-xxj-ajaxFileUpload.js 无刷新上传图片 jquery 插件,支持 ie6-ie10 依赖:jquery-1.6.1.min.js 主方法:ajaxFileUpl ...
- 为什么不能用 JS 获取剪贴板上的内容?
为什么不能用 JS 获取剪贴板上的内容? 为什么不能用 JS 获取剪贴板上的内容? 发一串口令给朋友朋友复制这串口令,然后访问你的网站你在网站上用 JS 读取朋友剪贴板上的口令根据不同的口令,显示不同 ...
- JS获取剪贴板图片之后的格式选择与压缩问题
前言 某年某月的某一天,突然发现博客服务器上上传的图片都比较大,一些很小的截图都有几百kb,本来服务器带宽就慢,不优化一下说不过去. 问题细述 特别说明:本文代码因为只是用于我自己后台写markdow ...
- 原生js复制粘贴上传图片前后台代码,兼容firebox,chrome, ie11,亲测有效
需求:粘贴上传图片,截图工具,右键粘贴,或者ctrl+v粘贴 方法1:可直接套用富文本框的图片上传功能,完成复制粘贴 缺点:麻烦,样式难控制 方法2:用原生js完成,以下案例基于此,样式请自己动手调整 ...
- js无刷新上传图片,服务端有生成缩略图,剪切图片,iphone图片旋转判断功能
html: <form action="<{:AppLink('circle/uploadimg')}>" id="imageform" me ...
- js php xmlrequest 上传图片
本来想用插件上传图片的,后来自己写了一个简单的js实现异步的图片上传,不多说上代码很easy upload.php <?php if(isset($_FILES["myfile&quo ...
- Asp.Net MVC 中JS通过ajaxfileupload上传图片获取身份证姓名、生日、家庭住址等详细信息
客户要求用身份证图片上传获取身份证的详细信息就下来研究了一下(现在的客户真的懒 身份证信息都懒得输入了哈哈...),经过慢慢研究,果然皇天不负有心人搞出来了.这个借助的是腾讯的一个SKD 腾讯优图云 ...
- js前台检测上传图片大小的总结
最近一直在做上传图片的前端检测,不通过后台就完成这个动作.但实际是,实际效果差强人意. html5的fileApi出来后,对文件的处理才变得方便了些,对它的简单介绍可以看我的前面的博客.现在支持的浏览 ...
- js预览上传图片
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
随机推荐
- JavaScript千分符---正则实现
一般在JavaScript中实现千分符,是使用切割+连接一顿操作 这里尝试一下使用正则快速实现千分符 let num0 = '12' let num1 = '123' let num2 = '1234 ...
- JavaScript开发中常用的代码规范配置文件
一.jsconfig.json { compilerOptions: { target: 'es6', experimentalDecorators: true, allowSyntheticDefa ...
- 010 socket定义服务器
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Ne ...
- Vue学习笔记六:v-model 数据双向绑定
目录 v-model简介和适用范围 新建HTML 所见即所得 v-model模拟简易计算器 v-model简介和适用范围 Vue的一大特点之一就是数据的双向绑定,v-model就是实现这个功能的指令, ...
- 深入理解JAVA中的代理模式
前言 代理是什么 事故现场:我家的宠物今天生病了,而我又没有相关的医学知识,所以我只让我的宠物多喝热水吗? 结果显然是不行的,所以我需要去找宠物医生这些更专业的人来帮我的宠物治病. 这个时候,代理就出 ...
- Arrays和String单元测试 20175301
要求 在IDEA中以TDD的方式对String类和Arrays类进行学习 一.String类相关方法的单元测试 1.ChatAt的测试 代码: import org.junit.Test; impor ...
- 关于python环境配置的博客收藏
使用anaconda的pip来扩展anaconda的库: https://www.cnblogs.com/duan-qs/p/6289339.html 一个.py文件如何调用另一个.py文件中的类和函 ...
- windows 7 命令修改IP地址
netsh interface ip set address "本地连接" static 172.17.15.97 255.255.255.0 172.17.12.1
- [Reinforcement Learning] 动态规划(Planning)
动态规划 动态规划(Dynamic Programming,简称DP)是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于具有如下性质的问题: 具有最优子结构(Opt ...
- Hexo博客部署-使用github作为保存中转仓库
本篇是在VPS上搭建Hexo静态博客的第一篇博文,写本篇的目的一是纪念一下,二是作为一个部署文档保留. 博客地址 相关描述 VPS环境是在搬瓦工上安装的centos6(x86),1核,512MB,10 ...