如何通过js完成多个文件的上传

JavaScript016

如何通过js完成多个文件的上传,第1张

HTML5 file组件的新属性

accept : 如果在file组件中增加这个属性就可以直接控制上传的文件类型了,实在是很方便。

multiple:是否允许选择多个文件

HTML5 页面代码修改后

<img width="400" height="250"/><br />

<input type="file" id="pic" name="pic" onchange="printFileInfo()" accept="image/*" multiple="multiple"/>

<input type="button" value="上传图片" onclick="uploadFile()" /><br />

<div id="parent">

<div id="son"></div>

</div>

accept 的值可以参阅:IANA MIME 类型(标准 MIME 类型的完整列表),如果使用的是DW开发的话,软件本身就有提示。

如果选择了多个文件,可以用JS做循环打印,看看文件的名称,类型和大小,看演示代码

function printFileInfo(){

var picFile = document.getElementById("pic")

var files = picFile.files

for(var i=0i<files.lengthi++){

var file = files[i]

var div = document.createElement("div")

div.innerHTML = "第("+ (i+1) +") 个文件的名字:"+ file.name +

" , 文件类型:"+ file.type +" , 文件大小:"+ file.size

document.body.appendChild( div)

}

}

既然可以循环多文件的话,就可以尝试多文件上传了。

1、首先创建 XMLHttpRequest 对象

//这是全局变量。因为是示例,所以就没有判断浏览器类型,低版本IE这么写的话会出问题的

var xhr = new XMLHttpRequest()

2、上篇介绍了进度事件(Progress) , 这次实现 progress 和 error 2个事件

error:在请求发生错误时触发。

对应上传时发生错误导致的上传失败:uploadFailed()

//上传失败

function uploadFailed(evt) {

alert("上传失败")

}

progress:在接收相应期间持续不断触发。

对应上传进度方法:onprogress()

/**

* 侦查附件上传情况 ,这个方法大概0.05-0.1秒执行一次

*/

function onprogress(evt){

var loaded = evt.loaded //已经上传大小情况

var tot = evt.total //附件总大小

var per = Math.floor(100*loaded/tot) //已经上传的百分比

$("#son").html( per +"%" )

$("#son").css("width" , per +"%")

}

最后就是上传方法了,注意上面的html代码中上传用的方法也需要改成这个uploadFile()方法才能正常使用。

//上传文件

function uploadFile() {

//将上传的多个文件放入formData中

var picFileList = $("#pic").get(0).files

var formData = new FormData()

for(var i=0i<picFileList.lengthi++){

formData.append("file" , picFileList[i] )

}

//监听事件

xhr.upload.addEventListener("progress", onprogress, false)

xhr.addEventListener("error", uploadFailed, false)//发送文件和表单自定义参数

xhr.open("POST", "upload")

//记得加入上传数据formData

xhr.send(formData)

}

方式一:事先写好多个input.在点击时才显示。也就是说上传的最大个数是写死了的。

html

<p>

<a href='#' onclick='javascript:viewnone(more1)'>添加附件 </a>

<div id='more1' style='display:none'>

<input type="file" name="attach1" size="50"javascript:viewnone(more2)>

</span>

</div>

<div id='more2' style='display:none'>

<input type="file" name="attach2" size="50"'>

</div>

</p>

js

<SCRIPT language="javascript">

function viewnone(e){

e.style.display=(e.style.display=="none")?"":"none"

}

</script>

方式二:这种方式的动态多文件上传是实现了的,很简单的,不说废话看code

html

<input type="button" name="button" value="添加附件" onclick="addInput()">

<input type="button" name="button" value="删除附件" onclick="deleteInput()">

<span id="upload"></span>

js

<script type="text/javascript">

var attachname = "attach"

var i=1

function addInput(){

if(i>0){

var attach = attachname + i

if(createInput(attach))

i=i+1

}

}

function deleteInput(){

if(i>1){

i=i-1

if(!removeInput())

i=i+1

}

}

function createInput(nm){

var aElement=document.createElement("input")

aElement.name=nm

aElement.id=nm

aElement.type="file"

aElement.size="50"

//aElement.value="thanks"

//aElement.onclick=Function("asdf()")

if(document.getElementById("upload").appendChild(aElement) == null)

return false

return true

}

function removeInput(nm){

var aElement = document.getElementById("upload")

if(aElement.removeChild(aElement.lastChild) == null)

return false

return true

}

</script>

方式三:动态多文件上传,只是在oFileInput.click()这个地方,这样做就不能上传这个文件了,因为发现它在上传之时就把这个input中的文件置空了。很可能是为了安全着想吧!

另外还有一点就是说,click()只有在ie中才能正常运行。

虽说这种方式最终没能实现上传,但还是留下来参考,看看是否有人可以真正实现上传。

html

<A href="javascript:newUpload()">添加附件</A>

<TABLE width="100%" border="0" cellpadding="0" cellspacing="1">

<TBODY id="fileList"></TBODY>

</TABLE>

<DIV id="uploadFiles" style="display:block"></DIV>

js

<SCRIPT language="javascript">

//---新建上传

function newUpload(){

var oFileList = document.getElementById("fileList")

var fileCount = oFileList.childNodes.length + 1

var oFileInput = newFileInput("upfile_" + fileCount)

if(selectFile(oFileInput)){

addFile(oFileInput)

}

}

//----选择文件

function selectFile(oFileInput){

var oUploadFiles = document.getElementById("uploadFiles")

oUploadFiles.appendChild(oFileInput)

oFileInput.focus()

oFileInput.click()//不能这样做,可能是为了安全着想吧!

var fileValue = oFileInput.value

if(fileValue == ""){

oUploadFiles.removeChild(oFileInput)

return false

}

else

return true

}

//---新建一个文件显示列表

function addFile(oFileInput){

var oFileList = document.getElementById("fileList")

var fileIndex = oFileList.childNodes.length + 1

var oTR = document.createElement("TR")

var oTD1 = document.createElement("TD")

var oTD2 = document.createElement("TD")

oTR.setAttribute("id","file_" + fileIndex)

oTR.setAttribute("bgcolor","#FFFFFF")

oTD1.setAttribute("width","6%")

oTD2.setAttribute("width","94%")

oTD2.setAttribute("align","left")

oTD2.innerText = oFileInput.value

oTD1.innerHTML = '<A href="javascript:removeFile('+ fileIndex + ')">删除</A>'

oTR.appendChild(oTD1)

oTR.appendChild(oTD2)

oFileList.appendChild(oTR)

}

//---移除上传的文件

function removeFile(fileIndex){

var oFileInput = document.getElementById("upfile_" + fileIndex)

var oTR= document.getElementById("file_" + fileIndex)

uploadFiles.removeChild(oFileInput)

fileList.removeChild(oTR)

}

//---创建一个file input对象并返回

function newFileInput(_name){

var oFileInput = document.createElement("INPUT")

oFileInput.type = "file"

oFileInput.id = _name

oFileInput.name = _name

oFileInput.size="50"

//oFileInput.setAttribute("id",_name)

//oFileInput.setAttribute("name",_name)

//oFileInput.outerHTML = '<INPUT type=file id=' + _name + ' name=' + _name + '>'

//alert(oFileInput.outerHTML)

return oFileInput

}

</SCRIPT>

一、Servlet实现文件上传,需要添加第三方提供的jar包

下载地址:

1) commons-fileupload-1.2.2-bin.zip: 点击打开链接

2) commons-io-2.3-bin.zip:点击打开链接

接着把这两个jar包放到 lib文件夹下:

二:文件上传的表单提交方式必须是POST方式,

编码类型:enctype="multipart/form-data",默认是 application/x-www-form-urlencoded

比如:

<form action="FileUpLoad"enctype="multipart/form-data"method="post">

三、举例:

1.fileupload.jsp

<%@ page language="java" import="javautil*" pageEncoding="UTF-8"%>

<%

String path = requestgetContextPath()

String basePath = requestgetScheme()+"://"+requestgetServerName()+":"+requestgetServerPort()+path+"/"

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">

<title>My JSP 'fileuploadjsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css" href="stylescss">

-->

</head>

<body>

<!-- enctype 默认是 application/x-www-form-urlencoded -->

<form action="FileUpLoad" enctype="multipart/form-data" method="post" >

用户名:<input type="text" name="usename"><br/>

上传文件:<input type="file" name="file1"><br/>

上传文件: <input type="file" name="file2"><br/>

<input type="submit" value="提交"/>

</form>

</body>

</html>

2.实际处理文件上传的 FileUpLoad.java

package comservletfileupload

import javaioFile

import javaio*

import javaioIOException

import javaioPrintWriter

import javautilList

import javaxservletServletException

import javaxservlethttpHttpServlet

import javaxservlethttpHttpServletRequest

import javaxservlethttpHttpServletResponse

import orgapachecommonsfileuploadFileItem

import orgapachecommonsfileuploadFileUploadException

import orgapachecommonsfileuploaddiskDiskFileItemFactory

import orgapachecommonsfileuploadservletServletFileUpload

/**

*

* @author Administrator

* 文件上传

* 具体步骤:

* 1)获得磁盘文件条目工厂 DiskFileItemFactory 要导包

* 2) 利用 request 获取 真实路径 ,供临时文件存储,和 最终文件存储 ,这两个存储位置可不同,也可相同

* 3)对 DiskFileItemFactory 对象设置一些 属性

* 4)高水平的API文件上传处理 ServletFileUpload upload = new ServletFileUpload(factory)

* 目的是调用 parseRequest(request)方法 获得 FileItem 集合list ,

*

* 5)在 FileItem 对象中 获取信息, 遍历, 判断 表单提交过来的信息 是否是 普通文本信息 另做处理

* 6)

* 第一种 用第三方 提供的 itemwrite( new File(path,filename) )直接写到磁盘上

* 第二种 手动处理

*

*/

public class FileUpLoad extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

requestsetCharacterEncoding("utf-8")//设置编码

//获得磁盘文件条目工厂

DiskFileItemFactory factory = new DiskFileItemFactory()

//获取文件需要上传到的路径

String path = requestgetRealPath("/upload")

//如果没以下两行设置的话,上传大的 文件 会占用 很多内存,

//设置暂时存放的 存储室 , 这个存储室,可以和 最终存储文件 的目录不同

/**

* 原理 它是先存到 暂时存储室,然后在真正写到 对应目录的硬盘上,

* 按理来说 当上传一个文件时,其实是上传了两份,第一个是以 tem 格式的

* 然后再将其真正写到 对应目录的硬盘上

*/

factorysetRepository(new File(path))

//设置 缓存的大小,当上传文件的容量超过该缓存时,直接放到 暂时存储室

factorysetSizeThreshold(1024*1024)

//高水平的API文件上传处理

ServletFileUpload upload = new ServletFileUpload(factory)

try {

//可以上传多个文件

List<FileItem>list = (List<FileItem>)uploadparseRequest(request)

for(FileItem item : list)

{

//获取表单的属性名字

String name = itemgetFieldName()

//如果获取的 表单信息是普通的 文本 信息

if(itemisFormField())

{

//获取用户具体输入的字符串 ,名字起得挺好,因为表单提交过来的是 字符串类型的

String value = itemgetString()

requestsetAttribute(name, value)

}

//对传入的非 简单的字符串进行处理 ,比如说二进制的 图片,电影这些

else

{

/**

* 以下三步,主要获取 上传文件的名字

*/

//获取路径名

String value = itemgetName()

//索引到最后一个反斜杠

int start = valuelastIndexOf("\\")

//截取 上传文件的 字符串名字,加1是 去掉反斜杠,

String filename = valuesubstring(start+1)

requestsetAttribute(name, filename)

//真正写到磁盘上

//它抛出的异常 用exception 捕捉

//itemwrite( new File(path,filename) )//第三方提供的

//手动写的

OutputStream out = new FileOutputStream(new File(path,filename))

InputStream in = itemgetInputStream()

int length = 0

byte [] buf = new byte[1024]

Systemoutprintln("获取上传文件的总共的容量:"+itemgetSize())

// inread(buf) 每次读到的数据存放在 buf 数组中

while( (length = inread(buf) ) != -1)

{

//在 buf 数组中 取出数据 写到 (输出流)磁盘上

outwrite(buf, 0, length)

}

inclose()

outclose()

}

}

} catch (FileUploadException e) {

// TODO Auto-generated catch block

eprintStackTrace()

}

catch (Exception e) {

// TODO Auto-generated catch block

//eprintStackTrace()

}

requestgetRequestDispatcher("filedemojsp")forward(request, response)

}

}

System.out.println("获取上传文件的总共的容量:"+item.getSize())

3.filedemo.jsp

<%@ page language="java" import="javautil*" pageEncoding="UTF-8"%>

<%

String path = requestgetContextPath()

String basePath = requestgetScheme()+"://"+requestgetServerName()+":"+requestgetServerPort()+path+"/"

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">

<title>My JSP 'filedemojsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css" href="stylescss">

-->

</head>

<body>

用户名:${requestScopeusename } <br/>

文件:${requestScopefile1 }<br/>

${requestScopefile2 }<br/>

<!-- 把上传的图片显示出来 -->

<img alt="go" src="/upload/<%=(String)requestgetAttribute("file1")%>" />

</body>

</html>

4结果页面:

以上就是本文的全部