数据在drop事件的event.dataTransfer.files里面,拿到这个File对象之后就可以和输入框进行一样的操作了,即使用FileReader读取,或者是新建一个空的formData,然后把它append到formData里面。 第三种粘贴的方式,通常是在一个编辑框里操作,如把div的contenteditable设置为true: <div contenteditable="true"> hello, paste your image here </div> 粘贴的数据是在event.clipboardData.files里面: $("#editor").on("paste", function(event) { let file = event.originalEvent.clipboardData.files[0]; }); 但是Safari的粘贴不是通过event传递的,它是直接在输入框里面添加一张图片,如下图所示:
它新建了一个img标签,并把img的src指向一个blob的本地数据。什么是blob呢,如何读取blob的内容呢? blob是一种类文件的存储格式,它可以存储几乎任何格式的内容,如json: let data = {hello: "world"}; let blob = new Blob([JSON.stringify(data)], {type : 'application/json'}); 为了获取本地的blob数据,我们可以用ajax发个本地的请求: $("#editor").on("paste", function(event) { // 需要setTimeout 0等图片出来了再处理 setTimeout(() => { let img = $(this).find("img[src^='blob']")[0]; console.log(img.src); // 用一个xhr获取blob数据 let xhr = new XMLHttpRequest(); xhr.open("GET", img.src); // 改变mime类型 xhr.responseType = "blob"; xhr.onload = function () { // response就是一个Blob对象 console.log(this.response); }; xhr.send(); }, 0); }); 上面代码把blob打印出来是这样的:
能得到它的大小和类型,但是具体内容也是不可见的,它有一个slice的方法,可用于切割大文件。和File一样,可以使用FileReader读取它的内容: function readBlob(blobImg) { let fileReader = new FileReader(); fileReader.onload = function() { console.log(this.result); } fileReader.onerror = function(err) { console.log(err); } fileReader.readAsDataURL(blobImg); } readBlob(this.response); 除此,还能使用window.URL读取,这是一个新的API,经常和Service Worker配套使用,因为SW里面常常要解析url。如下代码: function readBlob(blobImg) { let urlCreator = window.URL || window.webkitURL; // 得到base64结果 let imageUrl = urlCreator.createObjectURL(this.response); return imageUrl; } readBlob(this.response); 关于src使用的是blob链接的,除了上面提到的img之外,另外一个很常见的是video标签,如youtobe的视频就是使用的blob:
这种数据不是直接在本地的,而是通过持续请求视频数据,然后再通过blob这个容器媒介添加到video里面,它也是通过URL的API创建的: let mediaSource = new MediaSource(); video.src = URL.createObjectURL(mediaSource); let sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'); sourceBuffer.appendBuffer(buf); 具体我也没实践过,不再展开讨论。 上面,我们使用了三种方式获取文件内容,最后得到: FormData格式 FileReader读取得到的base64或者ArrayBuffer二进制格式 如果直接就是一个FormData了,那么直接用ajax发出去就行了,不用做任何处理: let form = document.querySelector("form"), formData = new FormData(form), formData.append("fileName", "photo.png"); let xhr = new XMLHttpRequest(); // 假设上传文件的接口叫upload xhr.open("POST", "/upload"); xhr.send(formData); 如果用jQuery的话,要设置两个属性为false: $.ajax({ url: "/upload", type: "POST", data: formData, processData: false, // 不处理数据 contentType: false // 不设置内容类型 }); 因为jQuery会自动把内容做一些转义,并且根据data自动设置请求mime类型,这里告诉jQuery直接用xhr.send发出去就行了。 观察控制台发请求的数据: (责任编辑:admin) |