在web应用程序中使用文件

在阅读 ajax与axios【ajax中FileReader】的时候,遇到一个专题,就是这个题目,在web应用程序中一般会有哪些场景会使用文件?

本篇大量参考MDN资料

我们一个一个看

2.1 发送和接受二进制文件

先来看发送

var oReq = new XMLHttpRequest();
oReq.open("POST", url, true);
oReq.onload = function (oEvent) {
  // 上传完成后.
};

var bb = new BlobBuilder(); // 需要合适的前缀: window.MozBlobBuilder 或者 window.WebKitBlobBuilder
bb.append('abc123');

// 这里不可以用Blob构造函数,因为Blob构造只接受ArrayBuffer,ArrayBufferView,Blob,DOMString
// new Blob([])

oReq.send(bb.getBlob('text/plain'));

注意:XMLHttpRequest对象的send方法已被增强,可以通过简单的传入一个ArrayBuffer, Blob, 或者 File对象来发送二进制数据.

【了解】再来看接受,对于日常开发,拿到二进制数据一般很难会去操作它,都是展示数据

var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";
// 这里告诉浏览器,通过处理为arraybuffer,当然这里可以设置为Blob

oReq.onload = function (oEvent) {
  var arrayBuffer = oReq.response; // 注意:不是oReq.responseText
  if (arrayBuffer) {
    var byteArray = new Uint8Array(arrayBuffer);
    for (var i = 0; i < byteArray.byteLength; i++) {
      // 对数组中的每个字节进行操作
    }
  }
};

oReq.send(null);

2.2 访问被选择的文件

两种方式:

  • onsubmit事件,给form元素设置
  • onchange事件,给input元素设置
<form action="register.php" method="post" enctype="multipart/form-data"
    onsubmit="AJAXSubmit(this); return false;">
</form>

<input type="file" id="input" multiple onchange="handleFiles(this.files)">

之后,各自事件中就可以访问到File对象了,就不说了

2.3 使用拖放来选择文件

let dropbox;

dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);

看看各个回调函数如何处理

function dragenter(e) {
    e.stopPropagation();
    e.preventDefault();
}

function dragover(e) {
    e.stopPropagation();
    e.preventDefault();
}

dragenter和dragover都不需要处理额外内容,让默认处理和冒泡消失,重点在于drop

function drop(e) {
    e.stopPropagation();
    e.preventDefault();

    var dt = e.dataTransfer;
    var files = dt.files;
    // 拿到files了,就可以后续的处理了
    // 反观拖拽其实很简单,浏览器把大多数事情都做了

    handleFiles(files);
}

拿到了文件,之后我们来看一个例子:显示用户选择的图片的缩略图

function handleFiles(files) {
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        var imageType = /^image//;

        if (!imageType.test(file.type)) {
            continue;
        }

        var img = document.createElement("img");
        img.classList.add("obj");
        // 添加class,常见的可能是下面的方式(覆盖)
        // img.className = 'obj'
        img.file = file;
        preview.appendChild(img); // 假设"preview"就是用来显示内容的div

        var reader = new FileReader();
        reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
        reader.readAsDataURL(file);
    }
}

首先,需要明白几点:

  • 1略缩图实现关键在于reader.readAsDataURL,将File文件转化为data:URL,从而压缩了图片
  • 2向img上挂载了file属性,从而以后可以方便拿到原File文件
  • 3为什么不先将src挂载到img上再append到容器中呢?其实都是一样的,图片加载是异步的

先读到这里,下面是使用对象 URL

上面代码有一个 document.createElement很常见吧,但是它返回的是什么呢?Element

还有这里提到了拖拽,上次一个boss问我如何实现拖拽模板创建相应内容?我没答上来,这里研究研究

2.3.1 Element

Element 是一个通用性非常强的基类,所有 Document 对象下的对象都继承自它。这个接口描述了所有相同种类的元素所普遍具有的方法和属性。一些接口继承自 Element 并且增加了一些额外功能的接口描述了具体的行为。例如, HTMLElement 接口是所有 HTML 元素的基本接口,而 SVGElement 接口是所有 SVG 元素的基础。大多数功能是在这个类的更深层级(hierarchy)的接口中被进一步制定的。

image-20210608222712433

2.3.2 拖拽

概述文档:HTML 拖放 API

专题文档:拖拽操作

原文地址:https://www.cnblogs.com/nahaohao/p/14870316.html