XMLHttpRequest和Ajax的關係
ajax
是一種技術方案,但並不是一種新技術。
ajax
最核心的依賴是瀏覽器提供的XMLHttpRequest
對象。
所以我用一句話來總結兩者的關係:我們使用XMLHttpRequest
對象來發送一個Ajax
請求
XMLHttpRequest的發展歷程
XMLHttpRequest
一開始只是微軟瀏覽器提供的一個接口,後來各大瀏覽器紛紛效仿也提供了這個接口,再後來W3C對它進行了標準化,提出了XMLHttpRequest標準
。XMLHttpRequest
標準又分爲Level 1
和Level 2
。
相應的區別和用法參考:
你真的會使用XMLHttpRequest嗎?
阮一峯的XMLHttpRequest Level 2 使用指南
實例代碼
pom.xml
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!--json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.29</version>
</dependency>
<!--上傳文件-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ajax測試</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/resource/js/jquery3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/resource/js/ajax.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/resource/js/jqueryAjax.js"></script>
</head>
<body>
<h1>XMLHttpRequest level 1</h1>
<button onclick="xhr1_get()">xhr level 1 get請求</button>
<button onclick="xhr1_post()">xhr level 1 post請求</button>
<h1>jQuery ajax</h1>
<button id="jquery_ajax_get">jquery get請求</button>
<button id="jquery_ajax_post">jquery post請求</button>
<h1>XMLHttpRequest level 2</h1>
<button onclick="xhr2_get()">xhr level 2 get請求</button>
<button onclick="xhr2_post()">xhr level 2 post請求</button>
</body>
</html>
XMLHttpRequest level 1
ajax.js
//等到所有內容,包括外部圖片之類的文件加載完後,纔會執行
window.onload = function () {
console.log("文檔就緒後執行");
}
GET請求
function xhr1_get() {
var xhr = new XMLHttpRequest();
//默認是異步請求async:true
xhr.open("GET", "./xhr1Servlet?name=zhangsan&age=23", true);
//設置響應數據解析格式(優先級大於後端設置)
// xhr.overrideMimeType('text/html;charset=UTF-8');
xhr.onreadystatechange = function (e) {
if (this.readyState === 4 && this.status === 200) {
console.log(this.response);
}
}
xhr.send();
}
Xhr1Servlet.java
@WebServlet("/xhr1Servlet")
public class Xhr1Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//和前端設置只一處就可以了,get通常後端設置,後端設置瀏覽器響應頭才能看見
resp.setContentType("text/html;charset=UTF-8");
String name = req.getParameter("name");
String age = req.getParameter("age");
resp.getWriter().print("名字:" + name + "年齡:" + age);
}
}
POST請求
function xhr1_post() {
var data = "name=zhangsan&age=23";
var xhr = new XMLHttpRequest();
xhr.open("POST", "./xhr1Servlet", true);
//必須設置請求頭,因爲request.getParameter()獲取的參數只能是符合URL編碼格式的
// ajax的默認請求ContentType:text/plain(純文本)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function (e) {
if (this.readyState === 4 && this.status === 200) {
console.log(this.response);
}
}
//data數據格式必須符合URL編碼字符串格式,如:“param1=value1¶m2=value2”
xhr.send(data);
}
Xhr1Servlet .java
@WebServlet("/xhr1Servlet")
public class Xhr1Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//和前端設置只一處就可以了,get通常後端設置,後端設置瀏覽器響應頭才能看見
resp.setContentType("text/html;charset=UTF-8");
String name = req.getParameter("name");
String age = req.getParameter("age");
resp.getWriter().print("名字:" + name + " 年齡:" + age);
}
}
XMLHttpRequest level 2
xhr.send(data),data可以是什麼類型的數據
xhr.responseType用來指定xhr.response的數據類型
跨域資源共享 CORS 詳解
GET請求
function xhr2_get() {
var xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.open("GET", "./xhr2Servlet?name=zhangsan&age=23", true);
//註冊相關事件回調處理函數
xhr.onload = function (e) {
if (this.status == 200 || this.status == 304) {
console.log(this.response);
}
};
xhr.send();
}
Xhr2Servlet.java
@WebServlet("/xhr2Servlet")
public class Xhr2Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//默認轉換成了iso-8859-1的編碼格式;和前端設置一處就可以了
resp.setContentType("application/json;charset=UTF-8");
String name = req.getParameter("name");
String age = req.getParameter("age");
JSONObject data = new JSONObject();
data.put("名字:", name);
data.put("年齡:", age);
resp.getWriter().print(data);
}
}
POST請求
function xhr2_post() {
var formData = new FormData();
formData.append('name', 'zhangsan');
formData.append('age', 12);
var xhr = new XMLHttpRequest();
//設置xhr請求的超時時間
xhr.timeout = 30000;
//設置響應返回的數據格式
xhr.responseType = "json";
//創建一個 post 請求,採用異步
xhr.open('POST', './xhr2postServlet', true);
//註冊相關事件回調處理函數
xhr.onload = function (e) {
if (this.status == 200 || this.status == 304) {
console.log(this.response);
}
};
//FormData 類型,content-type默認值爲multipart/form-data
xhr.send(formData);
}
Xhr2postServlet.java
@WebServlet("/xhr2postServlet")
public class Xhr2postServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//默認轉換成了iso-8859-1的編碼格式;和前端設置一處就可以了
resp.setContentType("application/json;charset=UTF-8");
JSONObject data = new JSONObject();
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
InputStream inputStream = null;
try {
List<FileItem> fileItems = upload.parseRequest(req);
for (FileItem item : fileItems) {
//普通字段
if (item.isFormField()) {
String fieldName = item.getFieldName();
String value = item.getString("UTF-8");
if("name".equals(fieldName)){
data.put("名字:", value);
}
if("age".equals(fieldName)){
data.put("年齡:", value);
}
} else {
//文件名稱
String fileName = item.getName();
//文件輸入流
inputStream = item.getInputStream();
}
}
} catch (FileUploadException e) {
data.put("失敗原因:", e.getMessage());
} finally {
IOUtils.closeQuietly(inputStream);
}
resp.getWriter().print(data);
}
}
jQuery ajax
jqueryAjax.js
GET請求
//在 html 所有標籤(DOM)都加載之後,就會去執行
//DOM文檔對象轉換爲jQuery對象,然後通過ready(fn)註冊頁面加載事件,當頁面加載完畢後執行fn函數
$(document).ready(function(){
//AJAX 請求完成時運行的函數,$(document)表示DOM對象轉換爲jQuery對象
$(document).ajaxComplete(function () {
console.log("jqueryAjax請求結束");
});
//爲將來的 $.ajax()請求設置默認值,$.get()和$.post()不能觸發
$.ajaxSetup({
url:"./xhr1Servlet?name=zhangsan&age=25",
async:true,
type:"GET",
headers: {
"Accept" : "text/html; charset=utf-8",
"Content-Type": "text/html; charset=utf-8"
},
success:function(data){
console.log("ajax()請求結束,結果:" );
console.log(data);
}
});
$("#jquery_ajax_get").click(function() {
$.ajax();
$.get("./xhr1Servlet?name=zhangsan&age=23", function (data) {
console.log(data);
}, "text");
$.get("./xhr2Servlet", {"name": "zhangsan", "age": 23}, function (data) {
console.log(data);
}, "json");
});
});
POST請求
//在 html 所有標籤(DOM)都加載之後,就會去執行
//DOM文檔對象轉換爲jQuery對象,然後通過ready(fn)註冊頁面加載事件,當頁面加載完畢後執行fn函數
$(document).ready(function(){
$("#jquery_ajax_post").click(function() {
$.post("./xhr1Servlet?name=zhangsan&age=23", function (data) {
console.log(data);
}, "text");
$.post("./xhr2Servlet", {"name": "zhangsan", "age": 23}, function (data) {
console.log(data);
}, "json");
//運行報錯,因爲header is application/x-www-form-urlencoded
$.post("./xhr2postServlet", {"name": "zhangsan", "age": 23}, function (data) {
console.log(data);
}, "json");
});
});