本文共 1898 字,大约阅读时间需要 6 分钟。
一个需求:让用户使用剪切板来粘贴图片(而不是将图片保存到本地,然后再选取文件上传)
今天做图片上传时发现,不论是什么路径上传的文件,路径都变成了这种格式 “C:\fakepath\文件名”。
以前做图片上传时没留意过这个fakepath,直译过来是伪路径,网上搜了一下 说是浏览器为了保护用户的文件安全,隐藏了上传的真实路径,用fakepath代替,或者调整浏览器的相关安全设置可以解决这个问题。
首先要明确两点:
我们这里讨论的是前者——剪切板里的截图,暂不考虑后者。从剪切板粘贴图片的教程很多,这里总结一下,大致分为4步:
找到event数据中的我们需要的图片信息
e.clipboardData.items[0].type.indexOf('image') > -1
拿到图片的dataURL
var reader = new FileReader(), file = e.clipboardData.items[0].getAsFile();reader.onload = function(e){ //this.result 可以得到图片的base64}reader.readAsDataURL(file);
: The readAsDataURL method is used to read the contents of the specified Blob or File. When the read operation is finished, the becomes DONE, and the is triggered. At that time, the result attribute contains the data as a URL representing the file’s data as a base64 encoded string.
readAsDataURL 方法用来读Blob或File内容,当读操作完成之后,readyState 状态变成DONE,并触发 loadend 方法。此时,result 属性就包含了一个URL字符串,即文件数据的base64编码格式。
使用上传
var formData = new FormData(); formData.append('file', file , filename); //第三个是文件名
注意:在Chrome中能够直接通过clipboardData获取截图的图片数据,在火狐等浏览器中无法直接获取图片数据,所以可以在粘贴的时候hack一下,ff里编辑[contenteditable]时,粘贴一个图片,ff会把图片当作图文混排的插图将它转化为一个
<img/>
元素插进去,img的src属性就是base64的dataURL
参考资料及扩展:
除了 Clipboard API,这里还包括 Drag&Drop、FileReader、FileSaving、CopyAPI(“点击我拷贝到剪切板”这样的功能)的原生JavaScript实现demo。
base64转Blob
function base64ToBlob(base64Str){ var dataURI = base64Str; 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 (i = 0; i < byteString.length; i += 1) { intArray[i] = byteString.charCodeAt(i); } return intArray//new Blob([intArray], { type: mimeString}); //转成blob}