什么是 AJAX?

前言

学妹这学期新开了一门课《Script及AJAX开发技术》,然而临近学期末,她突然跑来问我:到底什么是AJAX ?相信很多人(尤其是前端)在写代码的时候经常会用到AJAX技术,但是如果真要说出个所以然,可能还会有些困难。其实简单概括下,AJAX就是一种利用 JavaScript 向服务端发起请求,并获得服务端响应的技术。它的特点是异步请求,局部刷新。

Tips:这里我将技术二字加粗了,是因为很多初学者会以为AJAX是一个库/框架,类似于JQuery/Vue之类的,因而有很多初学者会提出该怎么安装AJAX的问题。事实上AJAX是一种技术。

虽然概括起来很简单,但是AJAX技术的一些细节仍然值得我们思考,接下来我会详细的介绍。

AJAX 解决的问题

我们刚才说过了,AJAX是一种发送请求的技术,那在AJAX被发明前,浏览器是如何请求的呢?

  1. 地址栏。用户在地址栏输入 http://baidu.com ,按回车,就向 http://baidu.com 发起了一个请求。(同时页面刷新)
  2. a 标签。用户点击页面中的 a 链接,也会发起一个请求。(同时页面刷新)
  3. img 标签。页面中如果有 img 标签,那么就会发起一个对此图片的请求(页面没有刷新,但是只能请求图片)类似的还有 link 标签、script 标签,都可以对一类文件的请求。

在这三种方式中,除了第三种,其他两种方式想要发送一个请求,就必须要刷新页面,如果页面只有展示内容的话刷新一下自然无所谓,但倘若一个页面有很多的表单内容需要填写,而你在最后填写完成提交的时候才告诉你,其中某一个地方不符合要求,要你回去重填,然后刷新一下页面,内容都消失了,怕是当时就可能会气的暴走了吧。

也正是这种极端的用户体验让微软创新地开发了一个接口 ActiveXObject("Microsoft.XMLHTTP"),并在 IE 5.0 中开放给开发者用。通过该接口,浏览器可以向服务器发送请求并取回所需的数据,并在客户端采用 JavaScript 处理来自服务器的回应。这就是 AJAX 的前身。随后这种技术被谷歌的开发人员发现并运用在 Gmail 中,再然后就是 W3C 制定了一个标准用来规范 AJAX,至此 AJAX 算是正式成为每一个前端开发者的必备技能了。

通过 AJAX 技术,服务器和浏览器之间交换的数据大量减少,服务器回应更快了。同时,很多的处理工作可以在发出请求的客户端机器上完成,因此服务端的负荷也减少了许多。

AJAX 的原理

那 AJAX 的实现原理又是什么呢?我们先来看一下AJAX的定义,以下内容摘自维基百科:

AJAX即“Asynchronous JavaScript and XML”(异步的JavaScriptXML技术),指的是一套综合了多项技术的浏览器网页开发技术。

这里又出现了一个新的名词:异步。这个名词在计算机领域可以说是一个很重要的名词了,很多技术都离不开异步二字,比如Nodejs的异步非阻塞I/O模型,当然这就是题外话了。我们应该怎么理解这里的异步呢?

不急不急,我们先来看一个生活中非常常见的例子🌰:

这种场景在上学的时候很常见,其实AJAX的原理和上述流程很相似,不信你看下面:

在上述例子中,核心是班长(也就是HXR对象),班主任可以通过他传递消息(客户端构建XHR对象发送请求)然后收到响应。在班长去通知小明的过程中,班主任仍然可以继续手头的工作,这就是一个异步的过程。(果然生活处处皆学问)

那么我们又该如何在代码中使用这个XHR对象呢?

AJAX 的使用

XHR 的全称是 XMLHttpRequest,这是由微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现。这跟以前的技术最大的不同点在于「页面无需刷新」,仅此而已。

想要使用 AJAX 发起一个请求很简单,一共 4 步。

  1. 创建一个 XHR 对象(需要考虑浏览器差异)
var request=null;  
if (window.XMLHttpRequest)  
    {// 兼容 IE7+, Firefox, Chrome, Opera, Safari  
        xhr=new XMLHttpRequest();  
    } else{// 兼容 IE6, IE5 
        xhr=new ActiveXObject("Microsoft.XMLHTTP");  
} 
  1. 监听请求成功后的状态变化
request.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    console.log(request.responseText)
  }
};

第三行的 request.responseText 就是服务器返回的内容了(默认是字符串)

  1. 设置请求参数
request.open(method,url,async);

请求的三个参数分别是:请求的方法、请求的地址、和是否采用异步请求。

  1. 发送请求
request.send();

说实话,虽然只有4步,但是通过这种原生的方法发送请求还是觉得有些复杂,那有没有什么简单的方法呢?

AJAX 的其他使用方式

JQuery 使用AJAX

JQuery将上述过程封装的很好,使用起来也非常简单(只举出最简单的例子,详细还请移步官方文档):

$.get('url').then(function(response){
  // 这里的 response 就是返回的内容
})

Vue 使用 AJAX

vue官方推荐使用axios来进行请求,这里同样举出一个最简单的例子

getApiData:function() {
    //设置请求路径
    var url = "XXXXXX"; 
    // 发送请求:将数据返回到一个回到函数中
    // 并且响应成功以后会执行then方法中的回调函数
    axios.get(url).then(function(result) {
        // result是所有的返回回来的数据
        // 包括了响应报文行
        // 响应报文头
        // 响应报文体
        console.log(result.data);
    }); 
}

微信小程序使用AJAX

微信小程序的请求就是wx.request这个api,wx.request(一些对象参数),微信小程序不同于浏览器的ajax请求,可以直接跨域请求不用考虑跨域问题。

wx.request({
  url: 'test.php',
  data: {
     x: '' ,
     y: ''
  },
  header: {
      'Content-Type': 'application/json'
  },
  success: function(res) {
    console.log(res.data)
  }
})

拓展

HTTP状态码

看到这其实我们就可以发送数据了,那怎么接收返回的数据呢?事实上,这已经不是在AJAX的讨论范围了,但是作为一个拓展知识点,我还是想介绍下状态码这个东西。状态码的作用是服务器返回给客户端的用来描述HTTP请求的状态的。用来描述HTTP请求的状态码太多了,这里介绍一些常见的状态码。

  • 200 表示从请求成功
  • 301 表示永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。
  • 302 表示临时性重定向。
  • 404 表示服务器上找不到请求的资源。
  • 500 表示服务器端在执行请求时发生了错误。多半是因为Web应用存在的bug或某些临时的故障。
  • 503 表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

获取网页中的XHR请求

这时就有人可能会问了,有没有什么办法可以获取一个网页中的XHR请求呢?当然是有的,这一过程其实说的宽泛点其实就是抓包,这里我以掘金为例,介绍下获取网页中的XHR请求。

首先我们打开Chrome浏览器,然后进入开发者工具(按F12或者网页右击选择“检查”),选择Network选项卡,我们可以发现下面有很多东西,比如Filter、All、HXR、JS等等,通过这个工具这里我们可以看见一个网页渲染过程中的所有请求(不只是XHR,还有JS、CSS等)。

随后我们选择XHR,就会出现请求这个网页过程中的所有的XHR请求了。包括name、status、size等信息。

之前提到过了,我们通过XHR携带的数据返回给浏览器渲染页面,到底是怎么实现的呢?不急,我们先来看一下现在的页面是什么样的:

其实这些东西都在其中一个XHR中,于是我们随便点击一个名为query的XHR对象(其实并不是随便点击的😜),然后移到Response选项卡:

我们看到了很长的一段JSON数据,格式化后(这里我们可以直接切换到Preview选项卡)筛选出一部分可以看到:

是不是刚才那个页面里面的东西都在这里面呢?

简单分析下

既然都获取到请求数据了,再不分析下都感觉对不起这么多的数据了,让我们把选项卡从Response移到Headers上,我们惊讶的发现竟然出现了好多东西:

这里我们简单说明下各个参数:

General 部分

首先是General部分:

我们可以看出,请求地址是https://web-api.juejin.im/query,请求方法为POST方法,请求状态是200,也就是请求成功了,同时还可以知道这次请求的IP地址是119.254.97.159:443

Referrer Policy

这里说下Referrer Policy这个字段,这个字段解释起来有点小麻烦,我们知道当用户在浏览器上点击一个链接时,会产生一个 HTTP 请求,用于获取新的页面内容,而在该请求的报头中,会包含一个 Referrer,用以指定该请求是从哪个页面跳转页来的,常被用于分析用户来源等信息。但是也有成为用户的一个不安全因素,比如有些网站直接将 sessionid 或是 token 放在地址栏里传递的,会原样不动地当作 Referrer 报头的内容传递给第三方网站。所以就有了 Referrer Policy,用于过滤 Referrer 报头内容,目前是一个候选标准,不过已经有部分浏览器支持该标准。这里为 no-referrer-when-downgrade 的意思是指当发生降级(比如从 https:// 跳转到 http:// )时,不传递 Referrer 报头。但是反过来的话不受影响。通常也会当作浏览器的默认安全策略。

Headers 部分

接下来是Response Headers和Request Headers,这里说实话我觉得没什么好说的,稍微有些重要的就是请求体Content-Type,为什么说他重要呢?我们往下看。

接下来一段是Request PayloadForm Data我们比较熟悉,那这个Request Payload又是个什么东西呢?我们知道前端开发中经常会用到AJAX发送异步请求,对于POST类型的请求会附带请求数据。而常用的传参方式有两种,其一是Form Data,另一个就是Request Payload了。

那这两者有何区别呢?其实区别主要就是在Content-Type上,这也就是为啥我说他重要的原因。

Form Data 和 Request Payload 区别

  1. 如果请求头里设置Content-Type: application/x-www-form-urlencoded,那么这个请求被认为是表单请求,参数出现在Form Data里,格式为key=value&key=value&key=value...
  2. 原生的AJAX请求头里设置Content-Type:application/json,或者使用默认的请求头Content-Type:text/plain参,数会显示在Request payload块里提交,参数格式为JSON格式:{"key":"value","key":"value"…},可读性会更好。

Fetch API

既然XHR这么方便,是不是就没有不足之处呢?当然不是。XHR 很实用,但并不是一个设计优良的 API,在设计上并不符合职责分离原则,输入、输出以及状态都杂糅在同一对象中,并用事件机制来跟踪状态变化。并且,基于事件的模型与最近流行的 Promise 和 generator 异步编程模型不太友好。因此Fetch API横空出世,它旨在修正上述缺陷,它提供了与 HTTP 语义相同的 JS 语法,简单来说,它引入了 fetch() 这个实用的方法来获取网络资源。

当然由于文章篇幅有限,这里仅仅只是引出Fetch API,推荐阅读 http://bubkoo.com/2015/05/08/introduction-to-fetch/

最后

其实刚开始只是想简单介绍下 AJAX 的原理,但是后来发现用了班主任让班长找小明这例子之后,AJAX 的原理似乎也就明白了,便想着要不就扩展点吧,以至于整篇文章有将近一半的篇幅在写扩展的知识了。不过也不算喧宾夺主,毕竟也是 AJAX 衍生出的知识点。

如果你对本篇文章的内容有所疑问,可以在评论区写下你的观点;如果你觉得本篇文章对你有所帮助,希望可以扫描下方二维码关注公众号「01二进制」。您的支持是我前进的最大动力!

参考

  1. 「每日一题」AJAX 是什么?

  2. Ajax原理一篇就够了

  3. HTTP请求中的form data和request payload的区别

  4. Form Data vs Request Payload

  5. 微信开放文档

  6. fetch API 简介

  7. Referrer Policy 介绍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 什么是Ajax 目录 1.背景介绍 2.知识剖析 3.常见问题 4.解决方案 5.编码实战 6.扩展思考 7.参考...
    冷眸_c6b8阅读 273评论 0 0
  • 大家好,我是IT修真院成都分院第7期的学员韩建名,一枚正直纯洁善良的WEB前端程序员。 目录 1.背景介绍 2.知...
    inh_阅读 339评论 0 0
  • 1.背景介绍 什么是Ajax? AJAX即异步的JavaScript与XML技术,指的是一套综合了多项技术的浏览器...
    苟况劝学阅读 688评论 0 1
  • 1.背景介绍 什么是Ajax? AJAX即“Asynchronous JavaScript and XML”(异步...
    我叫于搞吧阅读 327评论 0 0
  • 大家好,我是IT修真院北京总院第21期的学员杨梦桐,今天这篇文章主要总结了ajax的内容 1. 什么是Ajax A...
    AmaYang阅读 350评论 0 0