利用XMLHttpRequest实现文件上传

微软最早以ActiveX对象的形式在IE5中引入了XMLHttpRequest对象,经Google发扬光大之后,目前所有的浏览器都已经支持XMLHttpRequest了,目前W3C正在制定XMLHttpRequest Level 2标准草案,相对于原来的XMLHttpRequest,新标准的XMLHttpRequest有了很大的改进,提供了很多新的功能。

本文就新旧XMLHttpRequest对象进行一个简单的比较,并介绍新标准的XMLHttpRequest对象的改进之处。

原来的XMLHttpRequest对象的缺点:

1.只支持文本数据的传递,不支持二进制数据。

2.传递数据的时候,没有progress事件,不能实时显示传递的进度信息。

3.受同源策略的限制,不能发送跨域的请求。

新标准的XMLHttpRequest的改进:

1.可以传递二进制数据。

2.在服务器端设置了允许跨域请求的时候,可以获取跨域的数据。

3.可以使用原生的FormData对象来管理要发送的表单数据。

4.提供了progress事件,可以提供进度信息。在下载和上传的时候,都有progress事件,下载的时候,progress事件由XMLHttpRequest本身触发,上传的时候,由XMLHttpRequest.upload对象触发。

 

利用新标准的XMLHttpRequest对象,我们可以非常方便的实现文件AJAX上传功能。

HTML:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<title>File Upload using XMLHttpRequest</title>
	<style type="text/css">
	.container {
        width: 500px;
        margin: 0 auto;
    }
    .progress-bar {
        border: 1px solid #000;
    }
    .progress {
        width: 0;
        background: #DEDEDE;
        height: 20px;  
    }
	</style>
</head>
<body>
	<div class="container">
		<p>
			选择文件:
			<input type="file" id="ipt-file"/>
			<button type="button" id="btn-upload">上传</button>
		</p>
		<div class="progress-bar">
			<div class="progress"  id="progress"></div>
		</div>
         <p id="info"></p> </div> <script src="./js/upload.js"></script> </body> </html>

JavaScript:

 upload.js的具体代码如下:

var button = document.querySelector("#btn-upload"),
	input = document.querySelector("#ipt-file"),
	progress = document.querySelector("#progress"),
	info = document.querySelector("#info");

var upload = function() {
	if (input.files.length === 0) {
		console.log("未选择文件");
		return;
	}

	var formData = new FormData();
	formData.append("file", input.files[0]);

	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState === 4) {
			console.log(xhr.responseText);
			info.innerHTML = xhr.responseText;
		}
	};

	xhr.upload.addEventListener("progress", function(event) {
		progress.style.width = Math.ceil(event.loaded * 100 / event.total) + "%";
	}, false);

	xhr.open("POST", "./upload");
	xhr.send(formData);
};

button.addEventListener("click", upload, false);

Java: 

上传服务端采用Servlet来实现。

package com.servlet;

import java.io.File;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet(description = "文件上传", urlPatterns = { "/upload" })
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private String filePath;
	private int maxFileSize = 1024 * 1024;

	public void init() {
		filePath = this.getServletContext().getRealPath("/") + File.separator
				+ "upload";
		File file = new File(filePath);
		if (!file.exists()) {
			file.mkdirs();
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, java.io.IOException {
		response.setContentType("text/plain");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setSizeMax(maxFileSize);

		try {
			List fileItems = upload.parseRequest(request);
			Iterator i = fileItems.iterator();
			while (i.hasNext()) {
				FileItem fi = (FileItem) i.next();
				if (!fi.isFormField()) {
					String fileName = fi.getName();
					File file = new File(filePath + File.separator + fileName);
					fi.write(file);
					out.println(fileName + "上传成功");
				}
			}
		} catch (Exception ex) {
			out.println("上传文件失败:" + ex.getMessage());
		} finally {
			out.close();
		}
	}
}

  

  

  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。