千家信息网

web开发中文件上传的实现方式有哪些

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,小编给大家分享一下web开发中文件上传的实现方式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!文件上传是Web开发常
千家信息网最后更新 2026年11月03日web开发中文件上传的实现方式有哪些

小编给大家分享一下web开发中文件上传的实现方式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

  文件上传是Web开发常见需求,上传文件需要用到文件输入框,如果给文件输入框添加一个multiple属性则可以一次选择多个文件(不支持的浏览器会自动忽略这个属性)

  

  点击这个输入框就可以打开浏览文件对话框选择文件了,一般一个输入框上传一个文件就行,要上传多个文件也可以用多个输入框来处理,这样做是为了兼容那些不支持multiple属性的浏览器,同时用户一般也不会选择多个文件

  (推荐学习:HTML视频教程)

  基本上传方式

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

  

  

  Upload

  

  这样上传方式是传统的同步上传,上传的文件如果很大,往往需要等待很久,上传完成后页面还会重新加载,并且必须等待上传完成后才能继续操作

  早期的浏览器并不支持异步上传,不过可以使用iframe来模拟,在页面中隐藏一个

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

  访问文件

  FileAPI提供了访问文件的能力,通过输入框的files属性访问,这会得到一个FileList,这是一个集合,如果只选择了一个文件,那么集合中的第一个元素就是这个文件

  varinput=document.querySelector('input[type="file"]')

  varfile=input.files[0]

  console.log(file.name)//文件名称

  console.log(file.size)//文件大小

  console.log(file.type)//文件类型

  支持FileAPI的浏览器可以参考caniuse

  Ajax上传

  由于可以通过FileAPI直接访问文件内容,再结合XMLHttpRequest对象直接将文件上传,将其作为参数传给XMLHttpRequest对象的send方法即可

  varxhr=newXMLHttpRequest()

  xhr.open('POST','/upload/url',true)

  xhr.send(file)

  不过一些原因不建议直接这样传递文件,而是使用FormData对象来包装需要上传的文件,FormData是一个构造函数,使用的时候先new一个实例,然后通过实例的append方法向其中添加数据,直接把需要上传的文件添加进去

  varformData=newFormData()

  formData.append('file',file,file.name)//第3个参数是文件名称

  formData.append('username','Mary')//还可以添加额外的参数

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

  varformData=newFormData(document.querySelector('form'))

  数据准备好后,就是上传了,同样是作为参数传给XMLHttpRequest对象的send方法

  varxhr=newXMLHttpRequest()

  xhr.open('POST','/upload/url',true)

  xhr.send(formData)

  监测上传进度

  XMLHttpRequest对象还提供了一个progress事件,基于这个事件可以知道上传进度如何

  varxhr=newXMLHttpRequest()

  xhr.open('POST','/upload/url',true)

  xhr.upload.onprogress=progressHandler//这个函数接下来定义

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

  functionprogressHandler(e){

  varpercent=Math.round((e.loaded/e.total)*100)

  }

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

  functionprogressHandler(e){

  if(e.lengthComputable){

  varpercent=Math.round((e.loaded/e.total)*100)

  }

  }

  支持Ajax上传的浏览器可以参考caniusehttps://caniuse.com/#feat=xhr2

  分割上传

  使用文件对象的slice方法可以分割文件,给该方法传递两个参数,一个起始位置和一个结束位置,这会返回一个新的Blob对象,包含原文件从起始位置到结束位置的那一部分(文件File对象其实也是Blob对象,这可以通过fileinstanceofBlob确定,Blob是File的父类)

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

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

  functionupload(file){

  letformData=newFormData()

  formData.append('file',file)

  letxhr=newXMLHttpRequest()

  xhr.open('POST','/upload/url',true)

  xhr.send(formData)

  }

  varblob=file.slice(0,1024)

  upload(blob)//上传第一部分

  varblob2=file.slice(1024,2048)

  upload(blob2)//上传第二部分

  //上传剩余部分

  通常用一个循环来处理更方便

  varpos=0//起始位置

  varsize=1024//块的大小

  while(pos

  letblob=file.slice(pos,pos+size)//结束位置=起始位置+块大小

  upload(blob)

  pos+=size//下次从结束位置开始继续分割

  }

  服务器接收到分块文件进行重新组装的代码就不在这里展示了

  使用这种方式上传文件会一次性发送多个HTTP请求,那么如何处理这种多个请求同时发送的情况呢?方法有很多,可以用Promise来处理,让每次上传都返回一个promise对象,然后用Promise.all方法来合并处理,Promise.all方法接受一个数组作为参数,因此将每次上传返回的promise对象放在一个数组中

  varpromises=[]

  while(pos

  letblob=file.slice(pos,pos+size)

  promises.push(upload(blob))//upload应该返回一个promise

  pos+=size

  }

  同时改造一下upload函数使其返回一个promise

  functionupload(file){

  returnnewPromise((resolve,reject)=>{

  letformData=newFormData()

  formData.append('file',file)

  letxhr=newXMLHttpRequest()

  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('Uploadsuccess!')

  }).catch((err)=>{

  console.log(err)

  })

  支持文件分割的浏览器可以参考caniuse

  判断一下文件对象是否有该方法就能知道浏览器是否支持该方法,对于早期的部分版本浏览器需要加上对应的浏览器厂商前缀

  varslice=file.slice||file.webkitSlice||file.mozSlice

  if(slice){

  letblob=slice.call(file,0,1024)//call

  upload(blob)

  }else{

  upload(file)//不支持分割就只能直接上传整个文件了,或者提示文件过大

  }

  拖拽上传

  通过拖拽API可以实现拖拽文件上传,默认情况下,拖拽一个文件到浏览器中,浏览器会尝试打开这个文件,要使用拖拽功能需要阻止这个默认行为

  document.addEventListener('dragover',function(e){

  e.preventDefault()

  e.stopPropagation()

  })

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

  varelement=document.querySelector('label')

  element.addEventListener('drop',function(e){

  e.preventDefault()

  e.stopPropagation()

  //...

  })

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

  varfile=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方便得多

以上是"web开发中文件上传的实现方式有哪些"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

文件 对象 属性 浏览 浏览器 输入 元素 位置 方法 支持 选择 事件 参数 表单 方式 多个 样式 处理 函数 同时 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州万易互联网科技有限公司 互联网属科技 北京互联网科技有限公司 致骋互联网科技 奇酷互联网科技公司 世界互联网领先科技成果 浩特互联网科技 互联网科技汛 海南购全球互联网科技 华中科技有哪些互联网大佬 博兴的互联网电子科技公司 互联网科技公司实习生 青岛科技大学互联网大赛研究生 互联网媒体平台算高科技产业 乌鲁木齐新华智原互联网科技学校 互联网公司黑科技创始人 四川慕妮娅互联网科技有限公司 互联网科技如何创业 昆明中奇联合互联网科技 普陀区互联网教育科技管理办法 互联网科技企业 互联网科技公司经营范围 开启互联网科技时代小说 哈尔滨新华互联网科技学院 互联网科技革命什么开始 亳州好赞互联网科技有限公司 迪庆互联网科技招生 四川互联网展示科技馆设计 神州科技互联网有限公司 互联网的科技体现在哪里
0