JavaScript-Ajax基础

概述

背景

在了解 AJAX 之前我们可以简单的认为「JavaScript 能力有限」,因为在此之前 Web 平台 提供所有的 API 都只停留在「单机」的阶段。这样就会造成一些无法实现的功能,例如:

  1. 无法在实现用户登录功能时,当用户输入邮箱地址显示用户对应的头像
  2. 无法在实现用户注册功能时,当用户输入邮箱或者用户名就提示是否存在
  3. 无法在实现留言板功能时,实时看到最新的用户留言

这些功能的开发最终都卡在一个相同的问题上:数据存放在服务端,无法通过已知的 API 获取。已知发送请求的方式:

  1. 地址栏输入地址,回车,刷新
  2. 特定元素的 href 或 src 属性
  3. 表单提交

这些方案都是我们无法通过或者很难通过代码的方式进行编程操作的。当需要对服务端发出请求并且接受服务端返回的响应时,我们可以通过 JavaScript 直接发送网络请求,那么 Web 的可能就会更多,随之能够实现的功能也会更多,至少不再是只能开发「单机游戏」。

Google Suggest

AJAX(Asynchronous JavaScript and XML),最早出现在 2005 年的 Google Suggest 上。它不是像 HTML、JavaScript 或 CSS 这样的一种“正式的”技术,它是在浏览器端进行网络编程(发送请求、接收响应)的技术方案,它使我们可以通过 JavaScript 直接获取服务端最新的内容而不必重新加载页面,让 Web 更能接近桌面应用的用户体验。

AJAX

AJAX 就是浏览器提供的一套 API,可以通过 JavaScript 调用,从而实现通过代码控制请 求与响应。实现通过 JavaScript 进行网络编程。XML 是最早在客户端与服务端之间传递数据时所采用的数据格式。应用于按需获取数据 、对用户数据校验、自动更新页面内容、提升用户无刷新体验等场景中。
免费数据接口:https://jsonplaceholder.typicode.com/


原生 AJAX

发送 AJAX 请求步骤:1、创建 XMLHttpRequest 类型的对象;2、准备发送,打开与一个网址之间的连接;3、执行发送动作;4、指定 xhr 状态变化事件处理函数。

// 以下为拉勾教育课件内代码
// 1.创建一个 XMLHttpRequest 类型的对象  --- 相当于打开了一个浏览器
var xhr = new XMLHttpRequest();
// 2.打开一个与网址之间的连接  --- 相当于在地址栏输入网址
xhr.open("GET","https://jsonplaceholder.typicode.com/users");
// 3.通过连接发送一次请求 --- 相当于点击回车或者超链接
xhr.send(null);
// 4.指定 xhr 状态变化事件处理函数   --- 相当于处理网页呈现后的操作
xhr.onreadystatechange = function () {
  // 通过判断 xhr 的 readyState ,确定此次请求是否完成
  if (this.readyState === 4) {
    console.log(this.responseText)
  }
}

XMLHttpRequest 类型对象

AJAX API 中核心提供的是一个 XMLHttpRequest 类型,该类型是 window 的一个对象类型,所有的 AJAX 操作都需要使用到这个类型,但是存在一定的兼容问题,在 IE6 中并没有这个对象,因此需要兼容写法。

    // 以下为拉勾教育课件内代码
    // 1.创建一个 XMLHttpRequest 类型的对象 
    var xhr = null;
    // 兼容写法
    if (window.XMLHttpRequest) {
      // 标准浏览器
      xhr = new XMLHttpRequest();
    } else {
      // IE 6 浏览器
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }

open() 方法开启请求

本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我们发送出去的请求仍然是 HTTP 请求,同样符合 HTTP 约定的格式。

语法:xhr.open(method, url)

  • method:要使用的HTTP方法,字符串格式,比如「GET」、「POST」、「PUT」、「DELETE」、等。
  • url:要向其发送请求的 URL 地址,字符串格式
    // open() 方法开启请求
    xhr.open("GET","https://jsonplaceholder.typicode.com/users?id=1");
    xhr.open("POST","https://jsonplaceholder.typicode.com/users");

setRequestHeader() 方法设置请求头

该方法必须在 open() 方法和 send() 之间调用,一般 get 方法不需要设置,而 post 方法必须设置。

语法:xhr.setRequestHeader(header, value);

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

send() 方法发送请求

该方法用于发送 HTTP 请求。

语法:xhr.send(body)

  • body:在XHR请求中要发送的数据体,根据请求头中的类型进行传参。

如果是 GET 方法,无需设置数据体,可以传 null 或者不传参,如果想传参数则直接写在网站上。

xhr.send("name=harry&age=19");

readyState 属性

readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态,由于 readystatechange 事件是 在 xhr 对象状态变化时触发(不单是在得到响应时),也就意味着这个事件会被触发多次。

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

事件处理函数

一般都是在 readyState 值为 4 时,执行响应的后续逻辑。

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

同步与异步

同步:可以理解为一个人在同一个时刻只能做一件事情,在执行一些耗时的操作(不需要看管)不去 做别的事,只是等待。
异步:可以理解为在执行一些耗时的操作(不需要看管)去做别的事,而不是等待。

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

为了让这个事件可以更加可靠(一定触发),在发送请求 send() 之前,一定是先注册 readystatechange 这样不论是同步或异步都能触发成功,但是在工作中,没有特殊需求不要使用同步模式。


响应数据格式

XML

一种数据描述手段,基本现在的项目不用了,淘汰的原因:数据冗余太多。

JSON

JavaScript Object Notation,JavaScript 对象表示法,该方法也是一种数据描述手段,类似于 JavaScript 字面量方式,服务端采用 JSON 格式返回数据,客户端按照 JSON 格式解析数据。

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

    // js 对象字面量
    var obj = { name: "tom", age: 19 };
    // JSON 格式数据
    var str = '{"name": "tom","age": 80}';

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

JSON-Server

平时我们也会自己写一些数据,通过 Ajax 获取,所以需要在本地搭建一个临时服务器。json-server 是一个 Node 模块,运行 Express 服务器,你可以指定一个 json 文件作为 api 的数据源。 也就是说,我们可以使用它快速的搭建一个 web 服务器。
网址:https://github.com/typicode/json-server


原生 Ajax 用法

GET 请求

通常在一次 GET 请求过程中,参数传递都是通过 URL 地址中的 ? 参数传递。 一般在 GET 请求中,无需设置请求头,也无需设置响应体,可以传 null 或者干脆不传。

    var xhr = new XMLHttpRequest();
    // 发送 GET 请求
    xhr.open("GET", "http://localhost:3000/users?age=19");
    xhr.send(null);

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.send("name=lily&age=19&class=2");
    // 第二种
    xhr.setRequestHeader("Content-Type","application/json")
    // JSON 格式数据可以用字符串格式或者 stringify 的格式进行发送
    xhr.send(`{
      "name": "lulu",
      "age": 18,
      "class": 2
    }`);
    xhr.send(JSON.stringify({
      "name": "harry",
      "age": 18,
      "class": 1
    }));

处理响应数据渲染

客户端中拿到请求的数据过后最常见的就是把这些数据呈现到界面上。如果数据结构简单,可以直接通过字符串操作(拼接)的方式处理,但是如果数据过于复杂,字符串拼接维护成本太大,就不推荐了,可以使用模版引擎或者 ES6 提供的模板字符串。

封装 AJAX 库

自己封装一个 AJAX 函数主要是为了了解封装的过程,一般情况在开发中都是使用第三方提供的 AJAX 库,因 为它们可能更加严谨。 为了在后续的开发过程中可以更方便的使用这套 API,一般的做法都是将其封装到一个函数中以便调用。

    // 以下为拉勾教育课件内代码
    // 封装自己的 Ajax 函数
    /**
     * 参数1:{string}    method  请求方法
     * 参数2:{string}    url     请求地址
     * 参数3:{Object}    params  请求参数
     * 参数4:{function}  done    请求完成后执行的回调函数
   */ 
    function ajax(method, url, params, done) {
      // 统一将方法中的字母转大写,便于后面判断
      method = method.toUpperCase();
      // 书写 IE 6 的兼容
      var xhr = window.XMLHttpRequest 
      ? new XMLHttpRequest() 
      : new ActiveXObject("Microsoft.XMLHTTP");
      // 将对象格式的参数转为 urlencoded的格式
      var pairs = [];
      for (var k in params) {
        pairs.push(k + "=" + params[k]);
      }
      var str = pairs.join("&");
      // 判断是否是 get 方法,需要更改 url 的值
      if (method === "GET") {
        url += "?" + str;
      }
      // 创建打开一个连接
      xhr.open(method, url);
      var data = null;
      // 如果是 post 方法,需要设置请求头,还有请求体
      if (method === "POST") {
        xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        data = str;
      }
      xhr.send(data);
      // 执行回调函数
      xhr.onreadystatechange = function () {
        if (this.readyState !== 4) return;
        // 执行外部传进来的回调函数即可
        // 需要用到响应体
        done(JSON.parse(this.responseText));
      }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容

  • Ajax 没出现前,JavaScript 在大多数开发者眼里应该还是个玩具语言,毕竟在那个刀耕火种的年代,压根就没...
    橙色流年阅读 505评论 0 1
  • Google Suggest AJAX(Asynchronous JavaScript and XML),最早出现...
    amanohina阅读 323评论 0 1
  • Ajax 技术 第1章 认识Ajax 1.1 初识 ajax 我们平常上网,不管是注册账号,还是浏览网页,其本质就...
    春风之旅阅读 2,894评论 0 26
  • AJAX 一、同步交互与异步交互 客户端想服务器端发送请求,直到服务器端进行响应,这个过程中,用户是不能做任何其他...
    我是渐渐呀阅读 366评论 0 1
  • 一、同步交互与异步交互 客户端想服务器端发送请求,直到服务器端进行响应,这个过程中,用户是不能做任何其他事情的(等...
    挣脱吧小白阅读 602评论 0 2