AJAX的原理和加载JSON
AJAX(Async JavaScript And XML) → 用 JS 发请求和收响应
让我们通过使用 AJAX 来加载 CSS、JavaScript、HTML、XML 和 JSON,学会 AJAX 的原理和用法。
背景
AJAX 是浏览器上的功能
- 浏览器可以发请求,收响应
- 浏览器在 window 上加了一个
XMLHttpRequest
函数 - 用这个构造函数(类)可以构造出一个对象
- JS 通过它实现发请求,收响应
准备一个服务器
- 使用server.js作为我们的服务器
- 用
node server.js 8888
启动 - 添加
index.html
/main.js
两个路由:
if (path === "/index.html") {
response.statusCode = 200;
response.setHeader("Content-Type", "text/html;charset=utf-8");
response.write(`
<!DOCTYPE html>
<html>
<head><title>ajax</title></head>
<body><h1>AJAX demo</h1>
<script src="/main.js"></script>
</body>
</html>
`);
response.end();
} else if (path === "/main.js") {
response.statusCode = 200;
response.setHeader("Content-Type", "text/css;charset=utf-8");
response.write(`console.log("I am main.js")`);
response.end();
}
挑战 1-加载 CSS
- 以前我们用
<link rel=stylesheet href="1.css"/>
- 今天请用 AJAX 加载 CSS
四个步骤
- 创建
HttpRequest
对象(XMLHttpRequest
) - 调用对象的
open
方法 - 监听对象的
onload
&onerror
事件专业前端会改用
onreadystatechange
事件, 具体用法可以参考: XMLHttpRequest.onreadystatechange| MDN扩展阅读: ready state | MDN
在事件处理函数里操作 CSS 文件内容
- 调用对象的
send
方法(发送请求)具体可以看: XMLHttpRequest.send() | MDN
HTML:
<!DOCTYPE html>
<html>
<head>
<title>ajax</title>
<!— <link rel="stylesheet" href="/style.css" />
—>
</head>
<body>
<h1>AJAX demo 1</h1>
<p>
<button id="getCSS">request css</button>
</p>
<script src="/main.js"></script>
</body>
</html>
JavaScript:
console.log("我是main.js");
getCSS.onclick = () => {
const request = new XMLHttpRequest();
request.open("GET", "/style.css");
request.onload = () => {
console.log("request.response");
console.log(request.response);
console.log("成功啦");
// 创建style标签
const style = document.createElement("style");
// 填写style内容
style.innerHTML = request.response;
// 插到头里面
document.head.appendChild(style);
};
request.onerror = () => {
console.log("失败了...");
};
request.send();
};
挑战 2-加载 JS
- 以前我们用
<script src="2.js"></script>
- 今天请用 AJAX 加载 JS
四个步骤
- 创建
HttpRequest
对象(XMLHttpRequest
) - 调用对象的
open
方法 - 监听对象的
onreadystatechange
事件在事件处理函数里操作 JS 文件内容
- 调用对象的
send
方法(发送请求)
JavaScript:
console.log("I am main.js");
getJS.onclick = () => {
const request = new XMLHttpRequest();
request.open("GET", "/2.js");
request.onload = () => {
console.log(request.response);
const script = document.createElement("script");
script.innerHTML = request.response;
document.body.appendChild(script);
};
request.onerror = () => {};
request.send();
};
挑战 3-加载 HTML
- 以前我们不会加载
3.html
四个步骤
- 创建
HttpRequest
对象(XMLHttpRequest
) - 调用对象的
open
方法 - 监听对象的
onreadystatechange
事件在事件处理函数里操作 HTML 文件内容
- 调用对象的
send
方法(发送请求)
console.log("I am main.js");
getHTML.onclick = () => {
const request = new XMLHttpRequest();
request.open("GET", "/3.html");
request.onload = () => {
console.log(request.response);
const div = document.createElement("div");
div.innerHTML = request.response;
document.body.appendChild(div);
};
request.onerror = () => {};
request.send();
};
onreadystatechange 事件
使用原因:
onerror()
并没有很好的匹配 AJAX
- 用
onreadystatechange
重做一下挑战 1
getCSS.onclick = () => {
const request = new XMLHttpRequest();
request.open("GET", "/style.css");
request.onreadystatechange = () => {
// console.log(request.readyState);
if (request.readyState === 4) {
// 下载完成,但不知道是成功 2xx 还是失败 4xx 5xx
if (request.status >= 200 && request.status < 300) {
const style = document.createElement("style");
style.innerHTML = request.response;
document.head.appendChild(style);
} else {
alert("加载css失败");
}
}
};
request.send();
};
挑战 4-加载 XML
- 以前我们不会加载
4.html
四个步骤
- 创建
HttpRequest
对象(XMLHttpRequest
) - 调用对象的
open
方法 - 监听对象的
onreadystatechange
事件在事件处理函数里操作
responseXML
- 调用对象的
send
方法(发送请求)
XML:
<?xml version="1.0" encoding="UTF-8"?>
<message>
<warning>
Hello World
</warning>
</message>
JavaScript:
getXML.onclick = () => {
const request = new XMLHttpRequest();
request.open("GET", "/4.xml");
request.onreadystatechange = () => {
if ((request.readyState === 4) & (request.status === 200)) {
const dom = request.responseXML;
const text = dom.getElementsByTagName("warning")[0].textContent;
console.log(text.trim());
}
};
request.send();
};
总结
HTTP 是个框,什么都能往里装
- 可以装 HTML、CSS、JS、XML…
- 记得设置正确的
Content-Type
,这是好习惯 - 只要你知道怎么解析这些内容,就可以使用这些内容
解析方法
- 得到 CSS 之后生成 style 标签
- 得到 JS 之后生成 script 标签
- 得到 HTML 之后使用 innerHTML 和 DOM API
- 得到 XML 之后使用 responseXML 和 DOM API
- 不同类型的数据有不同类型的解析办法
挑战 5-加载 JSON
支持的数据类型
- string
(注意)只支持双引号,不支持单引号和无引号
- number
支持科学计数法
- bool
true 和 false
- null
没有 undefined
- object
- array
就这六种,注意跟 JS 的七种数据类型区别开来
不支持函数,不支持变量(所以也不支持引用)
加载 JSON
- 我们需要加载
5.json
四个步骤
- 创建 HttpRequest 对象(全称是 XMLHttpRequest)
- 调用对象的 open 方法
- 监听对象的 onreadystatechange 事件
在事件处理函数里使用
JSON.parse
- 调用对象的 send 方法(发送请求)
HTML:
<!DOCTYPE html>
<html>
<head>
<title>ajax</title>
</head>
<body>
<h1>AJAX Hello <span id="myName"></span></h1>
<p>
<button id="getJSON">request JSON</button>
</p>
<script src="/main.js"></script>
</body>
</html>
JSON:
{
"name": "xiu",
"age": 24,
"xxx": null
}
JavaScript:
getJSON.onclick = () => {
const request = new XMLHttpRequest();
request.open("GET", "/5.json");
request.onreadystatechange = () => {
if (request.readyState === 4 && request.status === 200) {
const object = JSON.parse(request.response);
myName.textContent = object.name;
}
};
request.send();
};
window.JSON
JSON.parse
- 将符合
JSON
语法的字符串转换成JS
对应类型的数据 JSON
字符串 →JS
数据- 由于
JSON
只有六种类型,所以转成的数据也只有 6 种 - 如果不符合
JSON
语法,则直接抛出一个Error
对象 - 一般用
try catch
捕获错误
JSON.stringify
- 是
JSON.parse
的逆运算 JS
数据 →JSON
字符串- 由于
JS
的数据类型比JSON
多,所以不一定能成功 - 如果失败,就抛出一个
Error
对象
全部 5 个挑战的完整代码