百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> web开发之文件上传的多种实现方式(附代码)
分享文章到:

web开发之文件上传的多种实现方式(附代码)

发布时间:09/01 来源:未知 浏览: 关键词:
本文为您介绍了web开发中常见的几种文件上传方式,包含根本上传、拜访文件上传、Ajax上传、分割文件上传、拖拽上传,但愿对学习HTML的伴侣有帮忙。文件上传是Web开发常见需求,上传文件需要用到文件输入框。

文件上传是 Web 开发常见需求,上传文件需要用到文件输入框,要是给文件输入框增加一个 multiple 属性则可以一次选中多个文件(不支撑的阅读器会主动忽略这个属性)

点击这个输入框就可以打开阅读文件对话框选中文件了,个别一个输入框上传一个文件就行,要上传多个文件也可以用多个输入框来处置,这样做是为了兼容那些不支撑 multiple 属性的阅读器,同时会员个别也不会选中多个文件

(举荐学习:HTML视频教程

根本上传方式

当把文件输入框放入表单中,提交表单的时候即可将选择的文件一起提交上传到办事器,需要注意的是因为提交的表单中包括文件,因而要修改一下表单元素的 enctype 属性为 multipart/form-data

这样上传方式是传统的同步上传,上传的文件要是很大,往往需要期待很久,上传完成后页面还会从新加载,而且必需期待上传完成后才干继续操纵

早期的阅读器并不支撑异步上传,不外可以运用 iframe 来模拟,在页面中隐蔽一个

这样在提交表单上传的时候,页面就不会从新加载了,取而代之的是 iframe 从新加载了,不外 iframe 原本就是隐蔽的,即便从新加载也不会感知到

拜访文件

File API 供给了拜访文件的能力,通过输入框的 files 属性拜访,这会得到一个 FileList,这是一个汇合,要是只选中了一个文件,那么汇合中的首先个元素就是这个文件

var input = document.querySelector('input[type="file"]')
var file = input.files[0]

console.log(file.name) // 文件名称
console.log(file.size) // 文件大小
console.log(file.type) // 文件类型

支撑 File API 的阅读器可以参照 caniuse

Ajax 上传

因为可以通过 File API 直接拜访文件内容,再联合 XMLHttpRequest 对象直接将文件上传,将其作为参数传给 XMLHttpRequest 对象的 send 办法即可

var xhr = new XMLHttpRequest()
xhr.open('POST', '/upload/url', true)
xhr.send(file)

不外一些缘由不倡议直接这样通报文件,而是运用 FormData 对象来包装需要上传的文件,FormData 是一个结构函数,运用的时候先 new 一个实例,然后通过实例的 append 办法向其中增加数据,直接把需要上传的文件增加进去

var formData = new FormData()
formData.append('file', file, file.name) // 第 3 个参数是文件名称
formData.append('username', 'Mary') // 还可以增加额外的参数

甚至也可以直接把表单元素作为实例化参数,这样整个表单中的数据就全部包括进去了

var formData = new FormData(document.querySelector('form'))

数据预备好后,就是上传了,一样是作为参数传给 XMLHttpRequest 对象的 send 办法

var xhr = new XMLHttpRequest()
xhr.open('POST', '/upload/url', true)
xhr.send(formData)

监测上传进度

XMLHttpRequest 对象还供给了一个 progress 事件,基于这个事件可以晓得上传进度怎样

var xhr = new XMLHttpRequest()
xhr.open('POST', '/upload/url', true)
xhr.upload.onprogress = progressHandler // 这个函数接下来定义

上传的 progress 事件由 xhr.upload 对象触发,在事件处置程序中运用这个事件对象的 loaded(已上传字节数) 和 total(总数) 属性来盘算上传的进度

function progressHandler(e) {
  var percent = Math.round((e.loaded / e.total) * 100)
}

上面的盘算会得到一个表示完成百分比的数字,不外这两个值也纷歧定总会有,保险一点先推断一下事件对象的 lengthComputable 属性

function progressHandler(e) {
  if (e.lengthComputable) {
    var percent = Math.round((e.loaded / e.total) * 100)
  }
}

支撑 Ajax 上传的阅读器可以参照 caniuse https://caniuse.com/#feat=xhr2

分割上传

运用文件对象的 slice 办法可以分割文件,给该办法通报两个参数,一个起始位置和一个完毕位置,这会返回一个新的 Blob 对象,包括原文件从起始位置到完毕位置的那一局部(文件 File 对象其实也是 Blob 对象,这可以通过 file instanceof Blob 肯定,Blob 是 File 的父类)

var blob = file.slice(0, 1024) // 文件从字节位置 0 到字节位置 1024 那 1KB

将文件分割成几个 Blob 对象离别上传就能实现将大文件分割上传

function upload(file) {
  let formData = new FormData()
  formData.append('file', file)
  let xhr = new XMLHttpRequest()
  xhr.open('POST', '/upload/url', true)
  xhr.send(formData)
}

var blob = file.slice(0, 1024)
upload(blob) // 上传首先局部

var blob2 = file.slice(1024, 2048)
upload(blob2) // 上传第二局部

// 上传剩余局部

平常用一个轮回来处置更利便

var pos = 0 // 起始位置
var size = 1024 // 块的大小

while (pos < file.size) {
  let blob = file.slice(pos, pos + size) // 结束位置 = 起始位置 + 块大小

  upload(blob)
  pos += size // 下次从结束位置开始继续分割
}

办事器接收到分块文件进行从新组装的代码就不在这里展现了

运用这种方式上传文件会一次性发送多个 HTTP 要求,那么怎样处置这种多个要求同时发送的状况呢?办法有许多,可以用 Promise 来处置,让每次上传都返回一个 promise 对象,然后用 Promise.all 办法来合并处置,Promise.all 办法承受一个数组作为参数,因而将每次上传返回的 promise 对象放在一个数组中

var promises = []

while (pos < file.size) {
  let blob = file.slice(pos, pos + size)

  promises.push(upload(blob)) // upload 应该返回一个 promise
  pos += size
}

同时革新一下 upload 函数使其返回一个 promise

function upload(file) {
  return new Promise((resolve, reject) => {
    let formData = new FormData()
    formData.append('file', file)
    let xhr = new XMLHttpRequest()
    xhr.open('POST', '/upload/url', true)
    xhr.onload = () => resolve(xhr.responseText)
    xhr.onerror = () => reject(xhr.statusText)
    xhr.send(formData)
  })
}

当一切完成后

Promise.all(promises).then((response) => {
  console.log('Upload success!')
}).catch((err) => {
  console.log(err)
})

支撑文件分割的阅读器可以参照 caniuse

推断一下文件对象可否有该办法就能晓得阅读器可否支撑该办法,关于早期的局部版本阅读器需要加上对应的阅读器厂商前缀

var slice = file.slice || file.webkitSlice || file.mozSlice

if (slice) {
  let blob = slice.call(file, 0, 1024) // call
  upload(blob)
} else {
  upload(file) // 不支撑分割就只能直接上传整个文件了,或者提醒文件过大
}

拖拽上传

通过拖拽 API 可以实现拖拽文件上传,默许状况下,拖拽一个文件到阅读器中,阅读器会尝试打开这个文件,要运用拖拽功能需要阻止这个默许行为

document.addEventListener('dragover', function(e) {
  e.preventDefault()
  e.stopPropagation()
})

任意指定一个元从来作为开释拖拽的区域,给一个元素绑定 drop 事件

var element = document.querySelector('label')
element.addEventListener('drop', function(e) {
  e.preventDefault()
  e.stopPropagation()

  // ...
})

通过该事件对象的 dataTransfer 属性猎取文件,然后上传即可

var file = e.dataTransfer.files[0]
upload(file) // upload 函数前面已经定义

选中类型

给文件输入框增加 accept 属性即可指定选中文件的类型,比方要选中 png 格局的图片,则指定其值为 image/png,要是要允许选中所有类型的图片,就是 image/*

增加 capture 属性可以调取设施性能,比方 capture="camera" 可以调取相机照相,不外这并不是一个规范属性,不一样设施实现方式也不同,需要注意

经测 iOS 设施增加该属性后只能照相而不克不及从相册选中文件了,所以推断一下

if (iOS) { // iOS 用 navigator.userAgent 推断
  input.removeAttribute('capture')
}

不支撑的阅读器会主动忽略这些属性

自定义样式

文件输入框在各个阅读器中呈现的模样都不大雷同,并且给 input 定义样式也不是那么利便,要是有需要利用自定义样式,有一个技巧,可以用一个 label 关联到这个文件输入框,当点击这个 label 元素的时候就会触发文件输入框的点击,打开阅读文件的对话框,相当于点击了文件输入框同样的结果


这时就可以将原本的文件输入框隐蔽了,然后给 label 元素任意地利用样式,究竟要给 label 元素利用样式比 input 利便得多

本文来自百分百源码网,html教程栏目,欢送学习

以上就是web开发之文件上传的多种实现方式(附代码)的细致内容,更多请关注 百分百源码网 其它相干文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有150人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板