更新日期:2022/04/10
  只要我们一起大笑,可怕的东西就会跑光光了。
只要我们一起大笑,可怕的东西就会跑光光了。
目録
1. AJAX 简介
- AJAX 工作原理
 AJAX 是基于现有的 Internet 标准并且联合使用它们:
 · XMLHttpRequest 对象 (异步的与服务器交换数据)
 · JavaScript/DOM (信息显示/交互)
 · CSS (给数据定义样式)
 · XML (作为转换数据的格式)

 
 
2. 快速开始
- 使用 XMLHttpRequest 发送 Ajax 请求的示例代码
 看注释应该可以明白大部分内容了。
<script>
    function myFunction() {
        // 构造表单数据
        let formData = new FormData();
        formData.append("userName", "Ouseki");
        formData.append("blog", "ITGodRoad");
        // 创建 XMLHTTPRequest 对象
        let xhr = new XMLHttpRequest();
        // 设置 xhr 请求的超时时间
        xhr.timeout = 3000;
        // 设置响应返回的数据格式
        xhr.responseType = "text";
        // 创建一个 post 请求,采用异步
        xhr.open('POST', "http://localhost:8080/ITGodRoad/testAjax.do", true);
        // 设置请求头的内容格式
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        // 注册相关事件回调处理函数
        const demo = document.getElementById("demo");
        xhr.onload = function () {
            //如果请求成功
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
                demo.innerHTML = xhr.responseText;
            }
        }
        xhr.ontimeout = function (e) {
            demo.innerHTML = "异步处理请求超时";
        };
        xhr.onerror = function (e) {
            demo.innerHTML = "异步处理发生错误";
        };
        xhr.upload.onprogress = function (e) {
            demo.innerHTML = "异步处理上传进度";
        };
        // 发送数据
        xhr.send(formData);
    }
</script>
- java 后台接收端代码
@RequestMapping(value = "/testAjax.do", produces = { "text/plain;charset=utf-8" }, method = RequestMethod.POST)
public String testAjax(HttpServletRequest request) {
    Map<String, String[]> parameterMap = request.getParameterMap();
    StringBuilder stringBuilder = new StringBuilder();
    for (String key : parameterMap.keySet()) {
        String[] value = parameterMap.get(key);
        stringBuilder.append(key).append(" : ").append(Arrays.toString(value)).append("\n");
    }
    return stringBuilder + "AJAX 请求成功!";
}
------WebKitFormBoundary 是浏览器从客户端向服务器端传送 HTML 标签数据(文本框、密码框、文件上传框 … )所使用的分隔符,一般会在分隔符后附加一串十六进制的数以示区别。网页元素都被嵌入于 form 表单,所以被称为 formboundary 。
 客户端需要把网页数据打包成一个数据包发送给服务器,组装的时候用分隔符把所有网页元素的标签数据分隔起来。服务器收到数据包后,先从数据包的头部固定位置寻找到分隔符字串,再据此拆分整个数据包并从中 一一 读取HTML的所有标签数据。

 
 
3. XMLHTTPRequest 对象
- XMLHTTPRequest 方法 / 属性
 XMLHttpRequest 对象用于和服务器交换数据。
| 方法 / 属性 | 描述 | 
|---|---|
| open(method,url,async) | 规定请求的类型1、URL 以及是否异步处理请求 | 
| send(data) | 将请求发送到服务器 | 
| setRequestHeader(header,value) | 向请求添加 HTTP 头2 | 
| getAllResponseHeaders() | 获取 response 中的所有 header 字段3 | 
| getResponseHeader(header) | 获取某个指定 header 字段的值 | 
| withCredentials | 布尔值类型,是否使用资格证书来创建一个跨站点访问控制请求,默认 false | 
| readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化4 | 
| status | 详见→浏览器状态码 | 
| responseType | 指定响应的数据类型,默认为字符串5 | 
| responseText | 获得字符串形式的响应数据 | 
| responseXML | 获得 XML 形式的响应数据 | 
3.1 XMLHTTPRequest 请求
- 创建 XMLHttpRequest 对象
 所有现代浏览器均内建了 XMLHttpRequest 对象,直接 new 即可。
let xhr = new XMLHttpRequest();
- 发送 GET 请求
 避免同一请求得到缓存结果,应向 URL 添加一个唯一的 ID。
// 加入随机数,避免得到缓存的结果
xhr.open("GET", "http://localhost:8080/ITGodRoad/testAjax.do?t=" + Math.random(), true);
// 发送带有普通参数的请求
xhr.open("GET", "http://localhost:8080/ITGodRoad/testAjax.do?userName=Ouseki&blog=ITGodRoad", true);
xhr.send();
- 发送 POST 请求
 如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定发送的数据。
 注意:设置请求头要在 open 之后。
*************************************************************************
// 构造表单数据
let formData = new FormData();
formData.append("userName", "Ouseki");
formData.append("blog", "ITGodRoad");
.........................................................................
// 发送 post 请求
xhr.open('POST', "http://localhost:8080/ITGodRoad/testAjax.do", true);
.........................................................................
// 模拟表单请求
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 如果 data 是 Document 类型,同时也是 HTML Document 类型,默认值为:
xhr.setRequestHeader("Content-type", "text/html");
// 如果 data 是 DOMString 类型,默认值为:
xhr.setRequestHeader("Content-type", "text/plain");
// 如果 data 是 FormData 类型,默认值为:(通常上传文件时使用此类型)
xhr.setRequestHeader("Content-type", "multipart/form-data");
.........................................................................
// post 普通参数
xhr.send("fname=Henry&lname=Ford");
// post 对象参数
xhr.send(formData);
*************************************************************************
 
 
3.2 XMLHTTPRequest 响应
如需获得来自服务器的响应,需使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
- 处理响应数据
 如果来自服务器的响应是 XML,需要对 XML 对象进行解析。
// responseText
document.getElementById("demo").innerHTML = xhr.responseText;
// responseXML 
const xmlDoc = xhr.responseXML;
let txt = "";
let data = xmlDoc.getElementsByTagName("ARTIST");
for (let i = 0; i < data.length; i++) {
    txt += data[i].childNodes[0].nodeValue + "<br>";
}
document.getElementById("demo").innerHTML=txt;
- xml 示例文件
 展示部分。
<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
	<CD>
		<TITLE>Empire Burlesque</TITLE>
		<ARTIST>Bob Dylan</ARTIST>
		<COUNTRY>USA</COUNTRY>
		<COMPANY>Columbia</COMPANY>
		<PRICE>10.90</PRICE>
		<YEAR>1985</YEAR>
	</CD>
	<CD>
		<TITLE>Hide your heart</TITLE>
		<ARTIST>Bonnie Tyler</ARTIST>
		<COUNTRY>UK</COUNTRY>
		<COMPANY>CBS Records</COMPANY>
		<PRICE>9.90</PRICE>
		<YEAR>1988</YEAR>
	</CD>
	<CD>
		<TITLE>Greatest Hits</TITLE>
		<ARTIST>Dolly Parton</ARTIST>
		<COUNTRY>USA</COUNTRY>
		<COMPANY>RCA</COMPANY>
		<PRICE>9.90</PRICE>
		<YEAR>1982</YEAR>
	</CD>
	...
<CATALOG>	
- demo
 完整 Demo 示例。
<script>
    function myFunction() {
      // 创建 XMLHTTPRequest 对象
      let xhr = new XMLHttpRequest();
      // 创建一个 get 请求,采用异步
      xhr.open('GET', "cd_catalog.xml", true);
        // 注册相关事件回调处理函数
        const demo = document.getElementById("demo");
        xhr.onload = function () {
            //如果请求成功
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
                const xmlDoc = xhr.responseXML;
                let txt = "";
                let data = xmlDoc.getElementsByTagName("ARTIST");
                for (let i = 0; i < data.length; i++) {
                    txt += data[i].childNodes[0].nodeValue + "<br>";
                }
                demo.innerHTML = txt;
            }
        }
        xhr.send();
    }
</script>
<div>
  <h3 id="demo">这是一个有趣的世界</h3>
  <button type="button" onclick="myFunction()">尝试一下</button>
</div>

 
 
【每日一面】
Http、XMLHttpRequest、Ajax 的关系
Http:是浏览器和 web 服务器交换数据的协议,规范。
 XMLHttpRequest:是浏览器实现的一组 api 函数,使用这些函数,浏览器再通过 Http 协议请求和发送数据。
 Ajax:不是一种技术,而是综合多种技术实现交互的模式名称:用 html 展示页面 + 使用 XMLHttpRequest 请求数据 + 使用 js 操作 dom
 Ajax 对象封装依赖 → XMLHttpRequest 对象封装依赖 → Http 协议
 
   
- method:请求的类型:GET 或 POST 
 url:文件在服务器上的位置
 async:true(异步)或 false(同步) ↩︎
- header: http 头的名称 
 value: http 头的值 ↩︎
- 客户端允许获取的 response header 字段只限于 “simple response header” 和 “Access-Control-Expose-Headers” 。如果调用限制以外的 header 字段,就会报 Refused to get unsafe header 的错误。 ↩︎ 
- 0: UNSENT 请求未初始化(还没有调用 open()) 
 1: OPENED 服务器连接已建立,但是还没有发送(还没有调用 send())
 2: HEADERS_RECEIVED 请求已发送,正在处理中(通常现在可以从响应中获取内容头)
 3: LOADING 请求处理中,正在下载响应体,通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
 4: DONE 响应已完成,您可以获取并使用服务器的响应了 ↩︎
- “text” String 字符串(不设置时默认为字符串) 
 “document” Document 对象(希望返回 XML 格式数据时使用)
 “json” javascript 对象
 “blob” Blob 对象
 “arrayBuffer” ArrayBuffer 对象 ↩︎










