千家信息网

用于web开发的文件上传怎么实现

发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,这篇"用于web开发的文件上传怎么实现"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"
千家信息网最后更新 2025年11月13日用于web开发的文件上传怎么实现

这篇"用于web开发的文件上传怎么实现"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"用于web开发的文件上传怎么实现"文章吧。

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

  

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

  基本上传方式

  当把文件输入框放入表单中,提交表单的时候即可将选中的文件一起提交上传到服务器,需要注意的是由于提交的表单中包含文件,因此要修改一下表单元素的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安全错误 数据库的锁怎样保障安全 贾汪区品质软件开发常见问题 连接mysql数据库的工具 数据库王珊第五版 pdf 数据库指定字符集的关键字 天眼查卖数据库吗 网络技术学习计划表模板 公司网络安全解决方案的流程 人体绘画软件开发 海康服务器设置远程管理 网页开发和软件开发相似吗 河北系统软件开发 手机 做服务器 国家网络安全周开幕式在线观看 db2数据库查询很快插入很慢 吴中区推广网络技术哪家好 数据库中的时间长度是什么 云环境下的软件开发要点 公共网络安全指定产品 广州数据库操作员兼职 徐州互联网软件开发推荐咨询 9.15正式服部落服务器推荐 保密和网络安全工作会议讲话 网络安全数据表格 沈阳软件开发有限公司 日语软件开发前景 软件开发违背职业道德例子 安卓软件怎么和服务器通讯啊 居民信息管理数据库 腾讯服务器工程师工资待遇 流媒体直播需要什么服务器
0