微軟最先以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(); } } }