ES5 推出了一系列的 API:
- BLOB (二进制大对象)
- File (文件接口,基于 BLOB,但是增加了文件相关的方法,比如路径,大小)
- FileList (借助 <input type="file">,来获取硬盘文件的一个接口)
- FileReader
- URL
1 Simple APIs
// 第一步,获取 input var fileInput = document.getElementById("myfile"); // 第二步,通过 input 获取 FileList var fileList = fileInput.files; // 第三步,通过 FileList 获取某个文件的对象 var file = fileList[0]; // 简单来说,获取 File 对象就是: file = document.getElementById('myfile').files[0];
一个图片 <img src="" > 的 src 可以使下面三个之一:
- 文件在操作系统中的路径
- DataURL 数据,用 Base64 编码,将二进制文件进行加密的过程,然后就可以使用这字符串来表示二进制文件了
- ObjectURL,它是我们需要使用的文件的一个引用字符串而已,格式为
blob:http://localhsot:8080/a3b05b0e-bd18-4b53-b6b8-0b345e9aebdb
2 Preview Demo
使用 ObjectURL:
myfile.onchange = function () { var imgUrl = URL.createObjectURL(myfile.files[0]); myimg.src = imgUrl; myimg.onload = () => URL.revokeObjectURL(imgUrl); };
3 Compress and Upload with AJAX
function shangchuantupian() { // 1. 获取图片的数据 // 2. 校验大小,如果超过尺寸,那么对其进行压缩 // 3. 加上你的水印 // 4. 调用 ajax 方式,将其发送到服务器 var canvas = document.createElement("canvas"); var image = new Image(); var imgUrl = URL.createObjectURL(myfile.files[0]); image.src = imgUrl; image.onload = () => { URL.revokeObjectURL(imgUrl); canvas.width = image.width / 2; canvas.height = image.height / 2; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0, image.width / 2, image.height / 2); ctx.fillText("nf147", image.width / 2 - 20, image.height / 2 - 20); canvas.toBlob(function (b) { var fd = new FormData(); fd.append("fff", b); fetch("/myupload", { method: 'post', body: fd }).then(resp => resp.body); }, "image/jpeg"); }; }
4 Compress and Upload [version 2]
HTML:
<style> #myimg { border: 3px solid gray; border-radius: 5px; position: absolute; top: 0; left: 0; } #mymask { position: absolute; top: 0; left: 0; } </style> <div class="container"> <div style="margin-top: 2em;"> <input type="file" id="myfile" style="display: none"> <!-- 选择文件后,要预览 --> <button class="btn btn-primary" onclick="myfile.click()">选择图片</button> <button class="btn btn-primary" onclick="clickMe()">上传图片</button> </div> <div style="position: relative"> <img src="" id="myimg" title="暂时没有上传" width="200" height="200"/> <canvas id="mymask" width="200" height="200">不支持canvas</canvas> </div> </div>
JS:
var ctx; myfile.onchange = () => { // 预览图片 var imgUrl = URL.createObjectURL(event.target.files[0]); myimg.src = imgUrl; myimg.onload = () => URL.revokeObjectURL(imgUrl); }; function clickMe() { compressImgWithCanvas(myfile.files[0], uploadWithAJAX); // uploadWithAJAX(myfile.files[0]); } /** * 压缩图片,然后执行某些任务 */ function compressImgWithCanvas(blob, taskCallback) { console.log("bbb"); var rat = 2; var w = myimg.naturalWidth / rat, h = myimg.naturalHeight / rat; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext('2d'); ctx.drawImage(myimg, 0, 0, w, h); ctx.fillText("nf147", w - 20, h - 20); canvas.toBlob(taskCallback, "image/jpeg"); } /** * 更新预览进度 */ function refreshProgress(r) { if (!ctx) ctx = mymask.getContext('2d'); ctx.save(); ctx.clearRect(0, 0, 200, 200); ctx.globalAlpha = 0.6; ctx.fillRect(0, (1 - r) * 200, 200, 200); ctx.globalAlpha = 1; ctx.fillStyle = "white"; ctx.font = "20px 微软雅黑"; ctx.fillText(r * 100 + '%', 80, 180); ctx.restore(); } /** * 通过 AJAX 上传 blob 类型的文件 * @param blob */ function uploadWithAJAX(blob) { var fd = new FormData(); fd.append("fff", blob); $.ajax({ method: 'post', url: "/myupload", cache: false, contentType: false, data: fd, processData: false, xhr: () => { var xhr = $.ajaxSettings.xhr(); xhr.upload.onprogress = (ev) => { refreshProgress(ev.loaded / ev.total); }; return xhr; } }).done(console.log) .fail((xhr, staus, err) => console.error(xhr, staus, err)); }