利用XMLHttpRequest實現文件上傳

微軟最先以ActiveX對象的形式在IE5中引入了XMLHttpRequest對象,經Google發揚光大以後,目前全部的瀏覽器都已經支持XMLHttpRequest了,目前W3C正在制定XMLHttpRequest Level 2標準草案,相對於原來的XMLHttpRequest,新標準的XMLHttpRequest有了很大的改進,提供了不少新的功能。javascript

本文就新舊XMLHttpRequest對象進行一個簡單的比較,並介紹新標準的XMLHttpRequest對象的改進之處。css

原來的XMLHttpRequest對象的缺點:html

1.只支持文本數據的傳遞,不支持二進制數據。java

2.傳遞數據的時候,沒有progress事件,不能實時顯示傳遞的進度信息。apache

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

新標準的XMLHttpRequest的改進:瀏覽器

1.能夠傳遞二進制數據。服務器

2.在服務器端設置了CORS容許跨域請求的時候,能夠獲取跨域的數據。app

3.能夠使用原生的FormData對象來管理要發送的表單數據。this

4.提供了progress事件,能夠提供進度信息。在下載和上傳的時候,都有progress事件,下載的時候,progress事件由XMLHttpRequest自己觸發,上傳的時候,由XMLHttpRequest.upload對象觸發,能夠經過addEventListener來添加事件處理方法。

 

利用新標準的XMLHttpRequest對象,咱們能夠很是方便的實現文件AJAX上傳功能。

HTML:

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="UTF-8">
		<title>使用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 && xhr.status === 200) {
			console.log(xhr.responseText);
			info.innerHTML = xhr.responseText;
		}
	};

	xhr.upload.addEventListener("progress", function(event) {
		if(event.lengthComputable){
			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();
		}
	}
}
相關文章
相關標籤/搜索