AJAX的原理

107 阅读4分钟

AJAX

  • 全称 Async JavaScript And XML

  • AJAX的全部内容:用 JS 发请求和收响应

背景

AJAX是浏览器上的功能

  • 浏览器可以发请求,收响应

  • 浏览器在 window 上加了一个 XMLHttpRequest 函数

  • 用这个构造函数(类)可以构造出一个对象

  • JS 通过它实现发请求,收响应

准备一个服务器

  • 使用 server.js 作为我们的服务器

  • 下载或复制代码即可用 node server.js 8888 启动

  • 添加 index.html / main.js 两个路由

if (path === '/page3') {
        response.statusCode = 200;
        response.setHeader("Content-Type", "text/json;charset=utf-8");
        response.write(fs.readFileSync("db/page3.json")); //以同步方式读取文件
        response.end();
    } else {
        response.statusCode = 404;
        response.setHeader("Content-Type", "text/html;charset=utf-8");
        response.write(`你输入的路径不存在对应的内容`);
        response.end();
    }
  • 注意:fs.readFileSync()方法是fs模块的内置应用程序编程接口,用于读取文件并返回其内容。

加载CSS

  • 以前用 <link rel=stylesheet href="1.css"/>

四个步骤

  • 创建 HttpRequest 对象(全称是 XMLHttpRequest)

  • 调用对象的 open 方法

  • 监听对象的 onload & onerror 事件

——专业前端会改用 onreadystatechange 事件

——在事件处理函数里操作 CSS 文件内容

  • 调用对象的 send 方法(发送请求)

——具体代码请打开 MDN 用 CRM 大法搞定

getCSS.onclick = () => {
  const request = new XMLHttpRequest();
  request.open("GET", "/style.css"); // readyState = 1
  request.onreadystatechange = () => {
    //下载成功,但不知道是成功 2xx 还是4xx 5xx
    if (request.readyState === 4) {
      if (request.status >= 200 && request.status < 300) {
        //创建style标签
        const style = document.createElement("style");
        //填写style内容
        style.innerHTML = request.response;
        //插到头里面
        document.head.appendChild(style);
      } else {
        alert("加载CSS失败");
      }
    }
  };
  request.send(); //readyState = 2
};

加载JS

  • 以前用 <script src="2.js"></script>

四个步骤

  • 创建 HttpRequest 对象(全称是 XMLHttpRequest)

  • 调用对象的 open 方法

  • 监听对象的 onreadystatechange 事件

——在事件处理函数里操作 JS 文件内容

  • 调用对象的 send 方法(发送请求)

——具体代码请打开 MDN 用 CRM 大法搞定

getJS.onclick = () => {
  const request = new XMLHttpRequest();
  request.open("GET", "/2.js");
  request.onreadystatechange = () => {
    if (request.readyState === 4) {
      if (request.status >= 200 && request.status < 300) {
        //创建 script 标签
        const script = document.createElement("script");
        //填写 script 内容
        script.innerHTML = request.response;
        //插到身体里面
        document.body.appendChild(script);
      } else {
        alert("加载js失败");
      }
    }
  };
  request.send();
};

加载HTML

  • 以前我们不会加载 3.html

四个步骤

  • 创建 HttpRequest 对象(全称是 XMLHttpRequest)

  • 调用对象的 open 方法

  • 监听对象的 onreadystatechange 事件

——在事件处理函数里操作 HTML 文件内容

  • 调用对象的 send 方法(发送请求)

——具体代码请打开 MDN 用 CRM 大法搞定

getHTML.onclick = () => {
 const request = new XMLHttpRequest();      
 request.open("GET", "/3.htm");             
 request.onload = () => {                   
  // 创建 div 标签                               
 const div = document.createElement("div"); 
  // 填写 div 内容                               
 div.innerHTML = request.response;        
 // 插入到身体里                                  
 document.body.appendChild(div);            
 };                                         
 request.onerror = () => {};                
 request.send();                            
};
  • 注意:onerror没有很好的匹配AJAX。所以用onreadystatechange

onreadystatechange 事件

  • XMLHttpRequest.onreadystatechange 会在 XMLHttpRequest 的readyState属性发生改变时触发 readystatechange 事件的时候被调用。

readystate的五个值

1.png

加载XML

  • 以前我们不会加载 4.xml

四个步骤

  • 创建 HttpRequest 对象(全称是 XMLHttpRequest)

  • 调用对象的 open 方法

  • 监听对象的 onreadystatechange 事件

——在事件处理函数里操作 responseXML

  • 调用对象的 send 方法(发送请求)

——具体代码请打开 MDN 用 CRM 大法搞定

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

  • 不同类型的数据有不同类型的解析办法

JSON(JavaScript Object Notation)

  • JSON 是一门语言,跟 HTML、CSS、XML、JS 一样,是一门独立的语言

  • JSON 不是编程语言是标记语言,跟 HTML、XML、Markdown 一样,用来展示数据

JSON 的铁轨图(参考json.org)

  • 在 JSON 中,它们采用以下形式:对象是一组无序的名称/值对。一个对象以{左大括号开始,以}右大括号结束。每个名称后跟冒号名称/值对由逗号分隔。

2.png

支持的数据类型

  • string - 只支持双引号,不支持单引号和无引号

  • number - 支持科学记数法

  • bool - true 和 false

  • null - 没有 undefined

  • object

  • array

  • 就这六种,注意跟 JS 的七种数据类型区别开来

  • 不支持函数,不支持变量(所以也不支持引用)

加载JSON

  • 我们需要加载 5.json

四个步骤

  • 创建 HttpRequest 对象(全称是 XMLHttpRequest)

  • 调用对象的 open 方法

  • 监听对象的 onreadystatechange 事件

——在事件处理函数里使用 JSON.parse

  • 调用对象的 send 方法(发送请求)

——具体代码请打开 MDN 用 CRM 大法搞定

getJSON.onclick = () => {
  const request = new XMLHttpRequest();
  request.open("GET", "/5.json");
  request.onreadystatechange = () => {
    if (request.readyState === 4 && request.status === 200) {
      console.log(request.response);
      const object = JSON.parse(request.response);
      myName.textContent = object.name;
      
      /*
      console.log(typeof request.response);
      console.log(request.response);
      const bool = JSON.parse(request.response);
      console.log(typeof bool);
      console.log(bool);
      */(布尔值)
    }
  };
  request.send();
};

window.JSON

JSON.parse

  • 将符合 JSON 语法的字符串转换成 JS 对应类型的数据

  • JSON 字符串 => JS 数据

  • 由于 JSON 只有六种类型,所以转成的数据也只有6种

  • 如果不符合 JSON 语法,则直接抛出一个 Error 对象

  • 一半用 try catch 捕获错误

let object
try{
  object = JSON.parse(`{'name':'frank'}`) //写的错误代码
} catch(error) {
  console.log('出错了,错误详情是')
  console.log(error)
  object = {'name':'no name'} //写出正常的代码
}
  console.log(object)

JSON.stringify

  • 是 JSON.parse 的逆运算

  • JS 数据 => JSON 字符串

  • 由于 JS 的数据类型比 JSON 多,所以不一定能成功

  • 如果失败,就抛出一个 Error 对象

加载分页

需求

  • 用户打开页面,看到第一页数据

  • 用户点击下一页,看到第二页数据

  • 用户点击下一页,看到第三页数据

  • 用户点击下一页,提示没用更多了

5.png

6.png