前端学习-AJAX基础

183 阅读5分钟

Asynchronous Javascript And XML

  • AJAX 就是浏览器提供的一套 API,可以通过 JavaScript 调用,从而实现通过代码控制请求与响应。实现通过 JavaScript 进行网络编程。
  • XML:最早在客户端与服务端之间传递数据时所采用的数据格式

发送 ajax 请求步骤

  • 创建 XMLHttpRequest 类型的对象
  • 准备发送,打开与一个网址之间的连接
  • 执行发送动作
  • 指定 xhr 状态变化事件处理函数

XMLHttpRequest 类型对象

AJAX API 中核心提供的是一个 XMLHttpRequest 类型,所有的 AJAX 操作都需要使用到这个类型。
var xhr = new XMLHttpRequest();
IE6 兼容
xhr = new ActiveXObject("Microsoft.XMLHTTP");

open() 方法开启请求

-本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我们发送出去的请求仍然是 HTTP 请求,同样符合 HTTP 约定的格式。
语法:xhr.open(method, url)
method:要使用的HTTP方法,比如「GET」、「POST」、「PUT」、「DELETE」、等。
url:要向其发送请求的 URL 地址,字符串格式。

setRequestHeader() 方法设置请求头

  • 此方法必须在 open() 方法和 send() 之间调用。
  • 语法:xhr.setRequestHeader(header, value);
  • header: 一般设置 “Content-Type” ,传输数据类型,即服务器需要我们传送的数据类型
  • value: 具体的数据类型,常用 "application/x-www-form-urlencoded" 和 "application/json"。

send() 方法发送请求

  • 用于发送 HTTP 请求
  • 语法:xhr.send(body)
  • body:在XHR请求中要发送的数据体,根据请求头中的类型进行传参。
  • 如果是 GET 方法,无需设置数据体,可以传 null 或者不传参。

readyState 属性

readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态,由于 readystatechange 事件是在 xhr 对象状态变化时触发(不单是在得到响应时),也就意味着这个事件会被触发多次,所以我们有必要了解每一个状态值代表的含义:

readyState状态描述说明
0UNSENT代理XHR被创建,但尚未调用open()方法
1OPENEDopen()方法已经被调用,建立了连接
2HEADERS_RECEIVEDsend()方法已经被调用,并且已经可以获取状态行和响应头
3LOADING响应体下载中,responseText属性可能已经包含部分数据
4DONE响应体下载完成,可以直接使用responseText

事件处理函数

  • 一般我们都是在 readyState 值为 4 时,执行响应的后续逻辑。
// 1.创建一个 XMLHttpRequest 类型的对象 
var xhr = null;
// 兼容写法
if (window.XMLHttpRequest) {
  // 标准浏览器
  xhr = new XMLHttpRequest();
} else {
  // IE 6 浏览器
  xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 2.open() 方法开启请求
// xhr.open("GET","https://jsonplaceholder.typicode.com/users?id=1");
xhr.open("POST","https://jsonplaceholder.typicode.com/users");
// 设置请求头
// 一般 get 方法不需要设置,而 post 方法必须设置
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 3.send() 方法发送一次请求
// 如果是 get 方法请求,不需要再 send 中传参数,它如果想传参数,直接写在网址上
// xhr.send(null);
xhr.send("name=harry&age=19");

xhr.onreadystatechange = function () {
  // 通过判断 xhr 的 readyState ,确定此次请求是否完成
  if (this.readyState === 4) {
    console.log(this.responseText)
  }
}

同步与异步

  • xhr.open() 方法第三个参数要求传入的是一个 boolean 值,其作用就是设置此次请求是否采用异步方式执行
  • 默认为 true 异步,如果需要同步执行可以通过传递 false 实现
  • 如果采用同步方式执行,则代码会卡死在 xhr.send() 这一步

响应数据格式

XML

  • 一种数据描述手段
  • 老掉牙的东西,简单演示一下,不在这里浪费时间,基本现在的项目不用了
  • 淘汰的原因:数据冗余太多

JSON

  • JavaScript Object Notation,JavaScript 对象表示法
  • 也是一种数据描述手段,类似于 JavaScript 字面量方式
  • 服务端采用 JSON 格式返回数据,客户端按照 JSON 格式解析数据
// js 对象字面量
var obj = {
  name: "tom",
  age: 19,
  cp: {
    name: "harry",
    age: 18
  }
};

// JSON 格式的数据,与 js 对象的区别
// 1.JSON 数据不需要存到变量中
// 2.结束时不需要写分号
// 3.JSON 数据中的属性名必须加引号

// JSON 对象
var str = '{"name": "tom","age": 80}';

console.log(obj);
console.log(JSON.stringify(obj));
// 使用 JSON 对象的 parse 方法可以将 json 格式的字符串转换成 对象格式,
// 具有了属性和方法,方便我们在js 中进行使用
console.log(JSON.parse(str));

注意

  • 不管是 JSON 也好,还是 XML,只是在 AJAX 请求过程中用到,并不代表它们与 AJAX 之间有必然的联系,它们只是数据协议罢了。
  • 不管服务端是采用 XML 还是采用 JSON 本质上都是将数据返回给客户端。
  • 服务端应该根据响应内容的格式设置一个合理的 Content-Type。

原生 AJAX 具体用法

GET 请求

  • 通常在一次 GET 请求过程中,参数传递都是通过 URL 地址中的 ? 参数传递。
  • 一般在 GET 请求中,无需设置请求头
  • 无需设置响应体,可以传 null 或者干脆不传
var xhr = new XMLHttpRequest();
// 发送 GET 请求
xhr.open("GET", "http://localhost:3000/users?age=19");
xhr.send(null);
xhr.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
}

POST 请求

  • POST 请求过程中,都是采用请求体承载需要提交的数据。
  • 需要设置请求头中的 Content-Type,以便于服务端接收数据
  • 需要提交到服务端的数据可以通过 send 方法的参数传递
var xhr = new XMLHttpRequest();
// post 请求
xhr.open("POST","http://localhost:3000/users");
// 设置请求头
// xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.setRequestHeader("Content-Type","application/json");
// xhr.send("name=lily&age=19&class=2");
// xhr.send(`{
//   "name": "lulu",
//   "age": 18,
//   "class": 2
// }`);
xhr.send(JSON.stringify({
  "name": "harry",
  "age": 18,
  "class": 1
}));
xhr.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
}

处理响应数据渲染

  • 客户端中拿到请求的数据过后最常见的就是把这些数据呈现到界面上。
  • 如果数据结构简单,可以直接通过字符串操作(拼接)的方式处理
  • 但是如果数据过于复杂,字符串拼接维护成本太大,就不推荐了
  • 可以使用模版引擎或者 ES6 提供的模板字符串
// 获取元素
var box = document.getElementById("box");
var xhr = new XMLHttpRequest();
// 发送 GET 请求
xhr.open("GET", "http://localhost:3000/users");
xhr.send(null);
xhr.onreadystatechange = function () {
  if (this.readyState === 4) {
    // 讲获取的响应体的字符串转为对象
    var data = JSON.parse(this.responseText)
    console.log(data);
    var str = "";
    // 循环遍历数组
    for (var i = 0 ; i < data.length ;i++) {
      // 进行字符串拼接 
      // str += "<tr><td>" + data[i].id + "</td><td>" + data[i].name + "</td><td>" + data[i].age + "</td><td>" + data[i].class + "</td></tr>";
      // 使用 模板字符串 进行拼接
      str += `<tr>
        <td>${data[i].id}</td>
        <td>${data[i].name}</td>
        <td>${data[i].age}</td>
        <td>${data[i].class}</td>
      </tr>`
    }
    box.innerHTML += str;
  }
};