概述
Ajax全称"Async Javascript And XML"即:异步的javascript和XML。它是一种称谓,并不指代某项具体的技术,准确来说是一系列技术的集合,所包含的有:
-
async:指Ajax能够创建异步的HTTP线程请求到服务器,Ajax的核心价值。
-
javascript:Ajax技术实现的载体平台,js内置对象XMLHttpRequest操作Ajax。
-
xml:一种具有通用性的数据格式,用在客户端和服务器交互数据,现在更多的使用json。
现在,所有的无刷新操作都被称为"Ajax",例如:jsonp技术。Ajax是能够像浏览器地址栏一样,发送HTTP请求到服务器的一种技术。更直白说的 它就是JS代码级别的浏览器,更为重要的是它可以创建异步的请求,以避免传统同步请求中跳转和页面刷新:
html: <a href="http://localhost"></a> 发送GET跳转页面
<form method="post"></form> 支持POST提交
js: location.href = "http://localhost" 发送GET跳转页面
命令行:curl http://localhost/index.html 系统工具发送HTTP
图形界面:在浏览器地址栏中输入URL地址 发起GET请求页面
Ajax调试:
火狐或者谷歌的开发者工具,进入控制台-> 网络-> xhr,查看Ajax请求的概况以及更为详细的信息
实现
Ajax实现的技术平台是Javascript,JS内建了XMLHttpRequest的系统类。XMLHttpRequest内置的方法用来实现Ajax的操作。换句话说 如果非要给Ajax打造一个核心技术,那就是XMLHttpRequest。
const xhr = new XMLHttpRequest;
console.log(xhr);
* 用来发送请求的一些方法:
* open()、send()、setRequestHeader()等
* 用来标记结果的一些属性:
* status/statusText、responseText/responseXML、readyState
* 监听请求过程的事件:
* onloadstart(请求开始事件), onprogress(服务端的处理), onloadend(请求完成的事件)
Ajax请求过程
一次Ajax操作 就是从客户端(JS)发送HTTP请求到服务器(JAVA/PHP)的过程,它可以被分为五个阶段,也叫五种状态,并且每种状态都由一个数字来标记它:
客户端创建Ajax并发送HTTP请求:
// 1、创建请求对象
const xhr = new XMLHttpRequest;
// 2、连接服务器设置:type类型,url地址,async是否异步(默认为true)
xhr.open('get', 'http://180.76.52.106/api/login.php?uname='+uname+'&password='+password);
// 3、设置HTTP头:option头部,value值(如果没有要求,可跳过)
xhr.setRequestHeader(option, value);
// 4、发送HTTP请求,设置请求体数据:data,GET请求则为null
xhr.send(data);
使用事件来监听状态
// 使用事件 来监听请求过程
xhr.onloadstart = function () { // 请求开始事件
console.log(xhr.readyState);// 0->1
}
xhr.onprogress = function () { // 在服务端的处理
console.log(xhr.readyState); // 1->2->3
}
xhr.onloadend = function () { // 请求完成的事件
console.log(xhr.readyState); // 3->4
}
onreadystatechange
对于Ajax不同状态的监听可以由一个事件函数来完成,即onreadystatechange
。它是当请求状态发生改变时触发的事件,共四次改变的过程:
0-1,1-2,2-3,3-4,也就是说该事件会被调用四次。
如果我们在事件函数体内打印状态值 则是改变之后的值,依次为:1,2,3,4。而通常我们要做的是 找到完成时状态并获取返回结果,这就需要我们添加判断状态值的条件。
xhr.onreadystatechange = function () {
// console.log(this.readyState);
if (xhr.readyState == 4) { // 请求完成
if (xhr.status == 200) { // 完成且成功
preview.innerHTML = xhr.responseText;
} else { // 完成 但有问题
preview.innerHTML = xhr.statusText;
}
} else { // 请求过程中
preview.innerHTML = "<img src='loading.gif' />"
}
}
常用方法和属性列表
属性或方法 | 用法用例 | 说明 |
---|---|---|
open | xhr.open(type, url, [,async]) | 和服务器建立连接的方法 |
send | xhr.send(data) | 发送请求的方法 并设置请求数据如果是GET则为null |
onloadstart | xhr.onloadstart = function () {} | 发送请求时 调用的事件处理函数 |
onprogress | xhr.onprogress = function () {} | 服务端处理请求时 触发的事件 |
onloadend | xhr.onloadend = function () {} | 请求完成时 触发的事件处理程序 |
onreadystatechange | xhr.onreadystatechange= function () { } | 请求状态改变时 触发的事件 |
readyState | xhr.readyState | 查看请求的状态值 |
responseText | xhr.responseText | 获取返回的结果 |
status | xhr.status | HTTP请求的状态码 |
statusText | xhr.statusText | HTTP文本消息 |
DONE | xhr.DONE | 完成时的状态值4 |
LOADING | xhr.LOADING | 处理中的状态值3 |
HEADERS_RECIEVED | xhr.HEADERS_RECIEVED | 服务器接收请求的状态值2 |
OPENED | xhr.OPENED | 客户端发出请求时的状态值 1 |
UNSENT | xhr.UNSENT | 请求未初始化时的状态值 0 |
GET请求数据随地址栏传输 ,外部可视 安全性低 数据容量有限 但是使用起来比较轻便 在没有特殊需求的情况下 也是一种选择。
(普通的A链接、location.href脚本跳转以及地址栏输入的http请求都是GET方式的请求)。
POST请求一般要借助表单来完成,表单中的数据在提交时会自动保存到请求体中,外部不可见 所以它的数据安全性高、且数据容量大。
ajax发送post请求
发送一个POST请求的两个要点:
① POST请求中 所有的数据需要在请求体中有组织或者有规律的组合在一起,这样服务端才能解析;而文本格式内容(text/html)通常也是按照url格式拼接的。
② POST请求中需要设置Content-Type头的文档类型,用以告知服务端POST来的数据是如何组装的,以便接收后解析它们;如果是url拼接的文本内容 需要设为”application/x-www-form-urlencoded”,其他例如二进制的文件等 则需要另作处理。
在form中 enctype属性用来设置编码类型 默认值为urlencoded,请求体中的数据 就会按照url格式组装
<form name="login" method="post" enctype="application/x-www-form-urlencoded">
<p>
账号:<input type="text" name="uname" value="" />
</p>
<p>
密码:<input type="password" name="usrpwd" value="" />
</p>
<p>
<input type="submit" value="登陆" />
</p>
</form>
在Ajax中 如果要发送POST请求 必须显式的去设置请求头中的Content-Type的值,一般也是application/x-www-form-urlencoded,并且接下来send中发送的数据 也要按照url格式来组装。
var xhr = new XMLHttpRequest;
// 设置请求行
xhr.open('post', 'http://180.76.52.106/api/post.php');
// 设置请求头 在get里面 没有特别的要求 可以不设置,但post要设置
// ajax的post不同于表单 会默认按照url格式组装
// ajax中需要手动声明请求体数据的组装格式,在头声明
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// post请求参数需要在这里设置 组装格式 必须和头声明的格式一致
xhr.send('a='+encodeURIComponent(a)+'&b='+encodeURIComponent(b));
URL参数编码
当请求参数的值中含有“/\?&”等特殊字符串时,在地址栏传输或者服务器解析时 会引起歧义。通常值会被截断 需要对使用url格式组装的数据(包括所有的GET请求中的参数值、POST请求中以URL编码的参数等) 进行转义,在JS中 使用encodeURIComponent函数来编码URL格式中参数的值,在PHP中 可以使用urldecode函数来解析参数值。