理解AJAX

AJAX, 是 Asynchronous JavaScript and XML, 即 javascript 的异步请求

发送请求的方法

  • 用 form 表单可以发送 GET 或者 POST 请求, 但是会刷新页面或新开页面
  • 用 a 可以发送 GET 请求,但是也会刷新页面或新开页面
  • 用 img 可以发送 GET 请求,但是只能以图片的形式展示
  • 用 link 可以发送 GET 请求,但是只能以 CSS、favicon 的形式展示
  • 用 script 可以发送 GET 请求,但是只能以脚本的形式进行

背景

微软在 IE5 中引入了 ActiveX 对象,使得 JS 可以发送 HTTP 请求,随后后面其他浏览器跟进,有了后来的 XMLHttpRequest,并纳入 W3C 规范

AJAX

  1. 使用 XMLHttpRequest 发送请求
  2. 服务器返回 XML 格式的字符串
  3. JS 解析 XML,并更新局部页面

下面是使用原生 JS 发送 AJAX 请求的前端 Demo

myButton.addEventListener('click', ()=> {
let request = new XMLHttpRequest();
// 配置 request
request.open('GET', '/xxx');
request.send();
request.onreadystatechange = function() {
if (request.readyState === 4) { // 请求响应都完成
if (request.status >= 200 && request.status < 300) {
// 请求成功,读取响应
console.log(request.responseText);
let parser = new DOMParser();
let xmlDoc = parser.parseFromString(request.responseText, 'text/xml');
let c = xmlDoc.getElementByTagName('content')[0].textContent;
// 使用 JSON 方式
// 把符合 JSON 语法的字符串,转换成 JS 对应的值
let string = request.responseText;
let object = window.JSON.parse(string);
} else if (request.status >= 400) {
// 请求失败
}
}
}
});

后端 node.js demo

...
else if (path === '/xxx') {
response.statusCode = 200;
response.setHeader('Content-Type', 'text/xml; charset=utf-8');
response.write(`
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<content>Don't forget me this weekend!</content>
</note>
`);
response.end();
}
...

JSON

全称: JavaScript Object Notation, 轻量级的数据交换语言,抄袭 JS 的语言,官网为 json.org, 由于其衍生自 JavaScript, 所以在某些地方跟 JavaScript 很像,比如传输的数据对象是由一些 “属性-值”对 以及 “数组数据类型” 组成

以下为 JavaScript 与 JSON 的区别

JavaScript JSON
undefined 没有
null null
[‘a’, ‘b’] [“a”, “b”]
function fn(){} 没有
{name: ‘frank’} {“name”, “frank”}
‘frank’ “frank”
var a = {};a.self = a 没有变量
{__proto__} 没有原型链

由此可以看出,JSON 只能用来表示 hash

  1. JSON 没有抄袭 function 和 undefined
  2. JSON 的字符串首尾必须是 "
  3. 需要补充的是,JSON 没有内置的 Date Math RegExp 等

则以上的 xml 可以表示为

// 原 xml
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<content>Don't forget me this weekend!</content>
</note>

// 转换成 JSON
{
"note": {
"to": "Tove",
"from": "Jani",
"heading": "Reminder",
"content": "Don't forget me this weekend!"
}
}

同源策略

CORS, 全称 Cross-Orign Resource Sharing (跨源资源共享)

只有/协议/域名/端口一模一样的才允许发 AJAX 请求

  1. http://baidu.com 可以向 http://www.baidu.com 发送 AJAX 请求嘛(不行)
  2. http://baidu.com:80 可以向 http://baidu.com:81 发送 AJAX 请求嘛(不行)

那么怎么才能从一个网站访问到另一个网站的响应数据呢,有一个方式是设置响应头 Access-Control-Allow-Orign

总结

手写一个基本的 AJAX 请求 (原生 JS)

let request = new XMLHttpRequest();
request.open('GET', 'http://demo.com');
request.send();
request.onreadystatechange = () => {
if (request.readyState === 4) {
if (request.status >=200 && request.status < 300) {
let string = request.responseText;
let object = window.JSON.parse(string);
}
}
}