AJAX请求
AJAX
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
1. 常识性知识
1.1 网页中如何请求数据
如果要在网页中请求服务器上的数据资源,则需要用到
XMLHttpRequest对象。
XMLHttpRequest(简称 xhr)是浏览器提供的 js 成员,通过它,可以请求服务器上的数据资源。
最简单的用法:
1 | var xhrObj = new XMLHttpRequest() |
1.2 资源的请求方式
客户端请求服务器时,请求的方式有很多种,最常见的两种请求方式分别为
get和post请求。
get请求通常用于获取服务端资源(向服务器要资源)例如:根据 URL 地址,从服务器获取 HTML 文件、css 文件、js文件、图片文件、数据资源等
post 请求通常用于向服务器提交数据(往服务器发送资源)
例如:登录时向服务器提交的登录信息、注册时向服务器提交的注册信息、添加用户时向服务器提交的 用户信息等各种数据提交操作
1.3 get、post的区别
Get请求的目的是给予服务器一些参数,以便从服务器获取列表.例如:
list.aspx?page=1,表示获取第一页的数据Post请求的目的是向服务器发送一些参数,例如form中的内容.与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
1、无法使用缓存文件(更新服务器上的文件或数据库)
2、向服务器发送大量数据( POST 没有数据量限制)
3、发送包含未知字符的用户输入时, POST 比 GET 更稳定也更可靠
若符合下列任一情况,则用GET方法:
1、请求是为了查找资源,HTML表单数据仅用来帮助搜索。
2、请求结果无持续性的副作用。
3、收集的数据及HTML表单内的输入字段名称的总长不超过1024个字符。
2. jQuery中的Ajax
浏览器中提供的
XMLHttpRequest用法比较复杂,所以 jQuery 对 XMLHttpRequest 进行了封装,提供了一系列 Ajax 相关的函数,极大地降低了 Ajax 的使用难度。
jQuery 中发起 Ajax 请求最常用的三个方法如下:
1 | $.get() |
2.1 $.get()的用法
1 | $.get(url, [data], [callback]) |
使用$.get() 函数发起带参数的请求时,示例代码如下:
1 | $.get('http://www.liulongbin.top:3006/api/getbooks', { id: 1 }, function(res) { |
2.2 $.post()函数的用法
jQuery 中
$.post()函数的功能单一,专门用来发起 post 请求,从而向服务器提交数据。
$.post()函数的语法如下:
1 | $.post(url, [data], [callback]) |
使用 $post() 向服务器提交数据的示例代码如下:
1 | $.post( |
2.3 $.ajax()函数的用法
相比于
$.get()、$.post()函数,jQuery 中提供的$.ajax()函数,是一个功能比较综合的函数,它允许我们对Ajax 请求进行更详细的配置。
$.ajax() 函数的基本语法如下:
1 | $.ajax({ |
使用 $.ajax()发起 GET 请求时,只需要将 type 属性的值设置为 ‘GET’ 即可:
1 | $.ajax({ |
使用 $.ajax()发起 POST 请求时,只需要将 type 属性的值设置为 ‘POST’ 即可:
1 | $.ajax({ |
3. XMLHttpRequest
XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,通过它,可以请求服务器上的数据资源 。之前所学的 jQuery 中的 Ajax 函数,就是基于xhr 对象封装出来的。
常用方法
1 | Open(string method,string url,boolean asynch,String username,string password) |
常用属性
1 | readyState |
3.1 使用xhr发起GET请求
1 | // 1. 创建 XHR 对象 |
3.2 xhr对象的readyState属性
XMLHttpRequest对象的 readyState 属性,用来表示当前 Ajax 请求所处的状态 。每个 Ajax 请求必然处于以下状态中的一个:

3.3 使用xhr发起带参数的GET请求
1 | // ...省略不必要的代码 |
这种在 URL 地址后面拼接的参数,叫做查询字符串 。
3.4 查询字符串
定义:查询字符串(URL 参数)是指在 URL 的末尾加上用于向服务器发送信息的字符串(变量)。
格式:将英文的?放在URL 的末尾,然后再加上 参数=值,想加上多个参数的话,使用 &符号进行分隔。以这个形式,可以将想要发送给服务器的数据添加到 URL 中。
1 | // 不带参数的 URL 地址 |
3.5 GET请求携带参数的本质
无论使用
$.ajax(),还是使用$ .get(),又或者直接使用 xhr 对象发起 GET 请求,当需要携带参数的时候,本质上,都是直接将参数以查询字符串的形式,追加到 URL 地址的后面,发送到服务器的。
1 | $.get('url', {name: 'zs', age: 20}, function() {}) |
3.6 使用xhr发起POST请求
1 | // 1. 创建 xhr 对象 |
4. URL编码与解码
4.1 什么是URL编码
URL 地址中,只允许出现英文相关的字母、标点符号、数字,因此,在 URL 地址中不允许出现中文字符。
- 如果 URL 中需要包含中文这样的字符,则必须对中文字符进行编码 (转义)。
- URL编码的原则:使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。
URL编码原则的通俗理解:使用英文字符去表示非英文字符。
1 | http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记 |
4.2 如何对URL进行编码与解码
浏览器提供了 URL 编码与解码的 API,分别是:
lencodeURI()编码的函数decodeURI()解码的函数
1 | encodeURI('黑马程序员') |
4.3 AJAX乱码问题
产生乱码的原因
1 | 返回的数据默认的字符编码是**utf-8* *,如果客户端页面是**gb2312**或者其它编码数据就会产生乱码  *** |
post方法提交数据默认的字符编码是utf-8 ,如果服务器端是gb2312或其他编码数据就会产生乱码
解决办法有
若客户端是gb2312编码,则在服务器指定输出流编码
服务器端和客户端都使用utf-8编码
1 | gb2312:header('Content-Type:text/html;charset=GB2312'); |
5.1 JSON和JS对象的互转:
要实现从 JSON 字符串转换为 JS 对象,使用
JSON.parse()方法:
1 | var obj = JSON.parse('{"a": "Hello", "b": "World"}') |
要实现从 JS 对象转换为 JSON 字符串,使用
JSON.stringify()方法:
1 | var json = JSON.stringify({a: 'Hello', b: 'World'}) |
5.2 序列化和反序列化
把数据对象转换为字符串的过程 ,叫做序列化 ,例如:
调用 JSON.stringify() 函数的操作,叫做 JSON 序列化。
把字符串转换为数据对象的过程 ,叫做反序列化 ,例如:调用 JSON.parse() 函数的操作,叫做 JSON 反序列化。
6. XMLHttpRequest Level2
旧版XMLHttpRequest的缺点
只支持文本数据的传输,无法用来读取和上传文件
传送和接收数据时,没有进度信息,只能提示有没有完成
XMLHttpRequest Level2的新功能
可以设置 HTTP 请求的时限
可以使用 FormData 对象管理表单数据
可以上传文件
可以获得数据传输的进度信息
6.1 设置HTTP请求时限
有时,Ajax 操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。新版本的 XMLHttpRequest 对象,增加了 timeout 属性,可以设置 HTTP 请求的时限:
1 | xhr.timeout = 3000 |
上面的语句,将最长等待时间设为 3000 毫秒。过了这个时限,就自动停止HTTP请求。与之配套的还有一个 timeout 事件,用来指定回调函数:
1 | xhr.ontimeout = function(event){ |
6.2 FormData对象管理表单数据
Ajax 操作往往用来提交表单数据。为了方便表单处理,
HTML5 新增了一个 FormData 对象,可以模拟表单操作:
1 | // 1. 新建 FormData 对象 |
FormData对象也可以用来获取网页表单的值,示例代码如下:
1 | // 获取表单元素 |
7. axios
Axios 是一个基于
promise网络请求库,作用于node.js 和浏览器中。在服务器端(Node),它依赖于本地Node.js HTTP模块,而在客户端(浏览器),它使用XMLHttpRequests。由于是同构的,Axios是少数几个在浏览器和服务器端都可以毫不费力地使用的库之一。
7.1 axios发起GET请求
axios 发起 get 请求的语法:
1 | axios.get('url', { params: { /* 参数 */ } }).then(callback) |
具体的请求示例如下:
1 | // 请求的 URL 地址 |
7.2 axios发起POST请求
axios 发起 post 请求的语法:
1 | axios.post('url', { /* 参数 */ }).then(callback) |
具体的请求示例如下:
1 | // 请求的 URL 地址 |
7.3 直接使用axios发起请求
axios 也提供了类似于 jQuery 中 $.ajax() 的函数,语法如下:
1 | axios({ |
8. 跨域和JSONP
8.1同源
如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源 。
例如,下表给出了相对于 http://www.test.com/index.html 页面的同源检测(默认80端口):
同源策略 (英文全称 Same origin policy)是浏览器提供的一个安全功能。
- MDN 官方给定的概念:同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
通俗的理解:浏览器规定,A 网站的 JavaScript,不允许和非同源的网站 C 之间,进行资源的交互,例如:无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB;无法接触非同源网页的 DOM;无法向非同源地址发送 Ajax 请求
8.2 跨域
同源指的是两个 URL 的协议、域名、端口一致,反之,则是跨域 。出现跨域的根本原因: 浏览器的同源策略不允许非同源的 URL 之间进行资源的交互。
下面这两个页面跨域
网页:http://www.test.com/index.html
接口:http://www.api.com/userlist
8.3 如何实现跨域数据请求
现如今,实现跨域数据请求,最主要的两种解决方案,分别是
JSONP和CORS。跨域主要是后端来解决,jsonp缺陷太大,基本上不使用。
- JSONP:出现的早,兼容性好(兼容低版本IE)。是前端程序员为了解决跨域问题,被迫想出来的一种临时解决方案。缺点是
只支持 GET 请求,不支持 POST 请求。
CORS:出现的较晚,它是 W3C 标准,属于请求的 。支持 GET 和 POST 请求。缺点是不兼容某些低版本的浏览器。
8.4 防抖与节流
防抖策略 (debounce)是当事件被触发后,延迟 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。应用场景:
用户在输入框中连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求,这样可以有效减少请求次数,节约请求资源;
- 节流策略 (throttle),顾名思义,可以减少一段时间内事件的触发频率。
①鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
②懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源;应用场景
控制轮播图的速度