当前位置: 首页 > news >正文

.form文件_一篇文章学会文件上传

e32ac223974bb5c54900e196d62c977b.png

文件上传

文件上传原理

文件上传的原理,就是DOM中的FileUpload对象。就是这句

<input type="file">

但仅仅这样并不足够。

文件上传本质上是需要按照特定的HTTP请求格式来处理文件,也就是在表单中将enctype="multipart/form-data"来实现。

multipart互联网上的混合资源,就是资源由多种元素组成,form-data表示可以使用HTML Forms 和 POST 方法上传文件,具体的定义可以参考RFC 7578。

当我们设置该属性后,请求体也发生了变化。

能够看到使用multipart/form-data上传文件中将会采用boundary来进行文件的分块处理。

dca9e1228f4509621b6690d948abe3a0.png

同步的文件上传

如下写法在IE时代将会是首选,采用form表单的同步上传功能实现文件的上传。

<form action="http://localhost:8100" method="POST" enctype="multipart/form-data">
	<input type="file" name="f1" id="f1">
    <input type="submit" id="bth">
</form>

我们用这个例子来理解下<input tyep="file">。我们将该元素打印出来。

let f1 = document.getElementById("f1")
console.log(f1.files)

如图所示,能够以数组的形式看到我们所选中的文件内容。

0cb26516a328c72c925860e797ae13e3.png

但这只是单文件的上传,对于多文件只需在标签中添加一个multiple即可。

<form action="http://127.0.0.1:1337" method="POST" enctype="multipart/form-data">
    <input type="file" name="f1" id="f1" multiple>
    <input type="submit" id="bth">
  </form>
</body>
<script>
  let f1 = document.getElementById("f1")
  console.log(f1.files)
</script>

979f35b71b2f19357189f2e289f27cde.png

异步的文件上传

上述只是文件的同步上传,但现在我们大多采取XMLHttprequest来进行异步的文件上传。

使用XMLHttprequest2进行文件上传在此简要介绍XMLHttpRequest所达到的好处。

  • 引入fileData类型来管理表单上传。
  • 新增xhr.upload.onprogress进行回调来实现上传进度的监听。
  • 可设置ontimeout来防止超时。
  • 依旧收同源策略影响,但可以在后端配置CORS来实现跨域。
<body>
  <input type="file" name="f1" id="f1" multiple>
  <button id="btn">上传</button>
</body>
<script>
  let btn = document.getElementById("btn")

  function upLoad() {
    let files = document.getElementById("f1").files
    let fileData = new FormData()
    let xhr = new XMLHttpRequest()
    for (let i = 0; i < files.length; i++) {
      fileData.append("files", files[i])
    }
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          //上传成功
        }
      }
    }
    xhr.open("POST", "http://127.0.0.1:1337", true)
    xhr.send(fileData)
  }
  btn.addEventListener("click", function () {
    upLoad()
    console.log("发起上传")
  }, false)
</script>

文件上传的进度

为了监控文件上传的进入,也就需要调用xhr.onload.onprogress方法进行上传百分比的计算。

xhr.upload.onprogress = function (e) {
     if(e.lengthComputable) {
      var percentComplete = (e.loaded / e.total) * 100;
       // 对进度进行处理
     }
  }

文件上传的拖拽

大体思路就是对拖拽的三个事件dragenter,dragover,drop进行监听,阻拦浏览器默认的拖拽打开事件,并阻止冒泡。最后获取到拖拽的文件。

<div id="dragBox" style="width: 300px;height: 300px; background-color: blanchedalmond;"></div>
let dragBox = document.getElementById("dragBox")
  dragBox.addEventListener("dragenter", handleDragenter, false)
  dragBox.addEventListener("dragover", handleDragover, false)
  dragBox.addEventListener("drop", handleDrop, false)  
function handleDragenter(e) {
    // 阻止浏览器默认拖拽进入事件、并防止冒泡
    e.stopPropagation()
    e.preventDefault()
  }

function handleDragover(e) {
    // 阻止浏览器默认拖拽覆盖事件、并阻止冒泡
    e.stopPropagation()
    e.preventDefault()
  }

function handleDrop(e) {
    // 阻止浏览器默认放下事件、并阻止冒泡
    e.stopPropagation()
    e.preventDefault()
    // 获取拖拽的文件
    let files = e.dataTransfer.files
  }

文件上传的预览

关于文件上传后的预览方式有很多,可以前后端联合,前端上传结束后再从后端获取图片。

也可以利用H5新增的FileReader来进行文件的读取。

<input type="file" name="f1" id="f1" multiple>
  <div id="preview"></div>

<script>
  document.getElementById("f1").addEventListener("change", function () {
    let preview = document.getElementById("preview")
    let img = document.createElement("img")
    let fileInput = document.getElementById("f1")
    let file = fileInput.files[0]
    img.width = 100
    img.height = 100
    preview.appendChild(img)
    // 使用H5的FileReader对象
    let reader = new FileReader()
    // 开始读取指定Blog中的内容
    reader.readAsDataURL(file)
    reader.onload = (e) => {
      img.src = e.target.result
    }
  }, false)
</script>

猛虎分享

一起进步

共勉

有需要的小伙伴可以关注微信公众号趣玩前端每日分享前端技术知识点。可进微信群和我们一起学习,一起探讨,还可以领取最新的前端学习资源。

2020前端最新学习资源(一)​mp.weixin.qq.com
c2b05da2b5896c7d54a6549de8da90b4.png

相关文章:

  • 2007年完美的理财计划模板
  • c++和java哪个难_Java和大数据学习哪个发展更好?Java转行大数据难吗?
  • Symbian中所体现的软件编程艺术
  • 23种设计模式_使用Go实现GoF的23种设计模式(三)
  • 白领:4大行业通往高薪之路
  • sql select distinct常见错误_切记,不要乱用SQL!一本介绍几种常见SQL错误用法。...
  • 描述cookie隔离的好处_??[译] 正交React组件的好处
  • CSDN英雄会上会英雄
  • bat批量查找文件并复制_Word还有这么超级实用的批量操作技巧,得学会
  • datagridview删除选中行_删除重复项见多了,但保留重复项要怎么做
  • python如何安装whl_python pip whl安装和使用
  • Symbian OS编码诀窍之设计诀窍
  • python程序语法元素的描述_python有哪些语法元素
  • Symbian屏幕双缓冲DSA
  • mysql如何判断当前扫描的是第一条记录_MySQL锁机制——你想知道的都在这了
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • docker python 配置
  • echarts的各种常用效果展示
  • echarts花样作死的坑
  • javascript 总结(常用工具类的封装)
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Markdown 语法简单说明
  • Odoo domain写法及运用
  • tweak 支持第三方库
  • vue中实现单选
  • Zsh 开发指南(第十四篇 文件读写)
  • 大整数乘法-表格法
  • 动态规划入门(以爬楼梯为例)
  • 构造函数(constructor)与原型链(prototype)关系
  • 理清楚Vue的结构
  • 每天一个设计模式之命令模式
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ###STL(标准模板库)
  • (1)(1.13) SiK无线电高级配置(六)
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (floyd+补集) poj 3275
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (理论篇)httpmoudle和httphandler一览
  • (图)IntelliTrace Tools 跟踪云端程序
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)Scala的“=”符号简介
  • .NET 5种线程安全集合
  • .net 程序发生了一个不可捕获的异常
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • .NET企业级应用架构设计系列之技术选型
  • .NET值类型变量“活”在哪?
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @private @protected @public
  • @Responsebody与@RequestBody
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [ 数据结构 - C++]红黑树RBTree
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [Erlang 0129] Erlang 杂记 VI 2014年10月28日
  • [HackMyVM]靶场 Wild