FileReader简单使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> body { padding: 0 2rem; } </style> </head> <body> <fieldset style="margin-top: 2rem"> <legend>图片预览:</legend> <input type="file" id="file" accept="image/*" /> <img src="" id="img" style="width: 50px" /> </fieldset> <fieldset style="margin-top: 2rem"> <legend>读取文本文件:</legend> txt,csv <input type="file" id="file1" /> <p id="text-progress"></p> <p id="text" style="min-height: 100px; height: auto; border: 1px solid silver"></p> </fieldset> <fieldset style="margin-top: 2rem"> <legend>检测图片真实类型:</legend> <input type="file" id="file2" /> <p>图片类型为:<span id="text-type1"></span></p> <p>MIME类型为:<span id="text-type2"></span></p> </fieldset> <fieldset style="margin-top: 2rem"> <legend>fetch Api:</legend> <img id="previewContainer1" style="width: 50px" /> <canvas id="canvas" width="50" height="50" style="border: 2px dashed grey"></canvas> <img id="previewContainer2" style="width: 50px" /> <img id="compressPrevContainer" width="50" height="50" style="border: 2px dashed green" /> </fieldset> <fieldset style="margin-top: 2rem"> <legend>大文件分片上传:</legend> <input type="file" id="file5" /> <p id="text5" style="height: 5opx"></p> </fieldset> <script> document.querySelector("#file").addEventListener("change", (e) => { const file = e.target.files[0]; const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (res) => { document.querySelector("#img").src = res.target.result; }; }); document.querySelector("#file1").addEventListener("change", (e) => { const file = e.target.files[0]; const reader = new FileReader(); reader.readAsText(file); reader.onloadstart = (res) => { if (res.total < 1) { reader.abort(); } }; reader.onload = (res) => { document.querySelector("#text").innerHTML = res.target.result; }; reader.onprogress = (res) => { const timer = setInterval(function () { const progress = (res.loaded / res.total).toFixed(2); if (progress == "1.00") clearInterval(timer); document.querySelector("#text-progress").innerHTML = progress * 100 + "%"; }, 100); }; reader.onabort = (res) => { console.log("aborted"); }; reader.onloadend = (res) => { console.log("loaded"); }; }); document.querySelector("#file2").addEventListener("change", (e) => { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = (res) => { const uint8Array = new Uint8Array(res.target.result); document.querySelector("#text-type1").innerText = check(uint8Array); document.querySelector("#text-type2").innerText = file.type; }; reader.readAsArrayBuffer(file.slice(0, 8)); }); function check(buffers) { const headers = { JPEG: [0xff, 0xd8, 0xff], PNG: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], GIF: [0x47, 0x49, 0x46, 0x38], BMP: [0x42, 0x4d], }; for (let type in headers) { if (headers[type].every((header, index) => header === buffers[index])) { return type; } } return ""; } </script> <script> const image1 = document.querySelector("#previewContainer1"); const image2 = document.querySelector("#previewContainer2"); fetch("https://avatars3.githubusercontent.com/u/4220799") .then((response) => response.blob()) .then((blob) => { image1.src = URL.createObjectURL(blob); image1.onload = () => { draw(image1); compress(); }; }); fetch("https://avatars3.githubusercontent.com/u/4220799") .then((response) => response.arrayBuffer()) .then((buffer) => { const blob = new Blob([buffer]); const objectURL = URL.createObjectURL(blob); image2.src = objectURL; }); function draw(image) { const canvas = document.querySelector("#canvas"); const ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0, 50, 50); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; const grayscale = function () { for (let i = 0; i < data.length; i += 4) { const avg = (data[i] + data[i + 1] + data[i + 2]) / 3; data[i] = avg; // red data[i + 1] = avg; // green data[i + 2] = avg; // blue } ctx.putImageData(imageData, 0, 0); }; grayscale(); } function compress(quality = 80, mimeType = "image/webp") { const compressImage = document.querySelector("#compressPrevContainer"); const canvas = document.querySelector("#canvas"); const imageDataURL = canvas.toDataURL(mimeType, quality / 100); compressImage.src = imageDataURL; } </script> <script> //大文件分片上传 document.querySelector("#file5").addEventListener("change", (e) => { // const file = new File(["a".repeat(1000000)], "test.txt"); const file = e.target.files[0]; const chunkSize = 400000; const url = "http://localhost/test.php"; async function chunkedUpload() { const totalChunk = Math.ceil(file.size / chunkSize); let i = 0; const files = []; for (let start = 0; start < file.size; start += chunkSize) { i++; const chunk = file.slice(start, start + chunkSize); const fd = new FormData(); fd.append("part", chunk); fd.append("filename", file.name); fd.append("total", totalChunk); fd.append("index", i); files.push(await fetch(url, { method: "post", body: fd }).then((res) => res.text())); } await fetch(url, { method: "post", headers: { "Content-Type": "application/json", // 'Content-Type': 'application/x-www-form-urlencoded', }, body: JSON.stringify({ files: files, filename: file.name }), }) .then((res) => res.text()) .then((res) => { document.querySelector("#text5").innerHTML = res; }); } chunkedUpload(); }); </script> </body> </html>
<?php
//大文件上传后端php代码 if (isset($_FILES['part'])) { //formdata格式 $to = './html-demos/uploads/' . time() . random_int(1000, 9999) . '.part'; move_uploaded_file($_FILES['part']['tmp_name'], $to); echo json_encode(['index' => $_REQUEST['index'], 'total' => $_REQUEST['total'], 'file' => $to]); die; } else { //json格式 $data = json_decode(file_get_contents('php://input'), true); $filename = $data['filename']; $tmp = explode('.', $filename); $type = $tmp[count($tmp) - 1]; $res = []; foreach ($data['files'] as $item) { $res[] = json_decode($item, 1); } usort($res, function ($itemA, $itemB) { return $itemA['index'] > $itemB['index']; }); $outFile = "./test." . $type; $out = fopen($outFile, 'a'); foreach ($res as $item) { $part = fopen($item['file'], 'rb'); flock($part, LOCK_EX); $contents = fread($part, filesize($item['file'])); flock($part, LOCK_UN); fwrite($out, $contents); @unlink($item['file']); } fclose($out); echo json_encode(['code' => 0, 'msg' => 'success']); die; }
参考文章:玩转前端二进制 (qq.com)