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)

 

posted @ 2022-11-16 22:16  carol2014  阅读(38)  评论(0编辑  收藏  举报