AJAX
AJAX 主要用于避免大量刷新页面,请求重复数据,通过AJAX可以不重载整个页面,只需要拿到自己希望渲染的部分数据即可
数据一般由后台服务器提供,也可以是本地文件
注意: 由于ajax请求时,不再需要返回整个页面,所以,这里只需要提供数据的一方以json等格式返回所需数据即可
Json
- 什么是Json
这是一种轻量级的数据交换格式,具备简洁和清晰的层次结构
目前几乎所有的编程语言,都支持内置的数据类型与json的互相转换,所以在实际的前后端开发过程中
前端工程师拿到的数据都是后端工程师处理好的json格式数据,前端工程师除了写好页面,还需要把这些json解析并渲染到页面
- Json对应的Js
| Json | 描述 | Js | 描述 |
|---|---|---|---|
| [] | 列表 | Array | 数组 |
| {} | 字典 | Object | 对象 |
| "" | 字符串 | String | 字符串 |
- 一个json格式的数据
{
"account": "admin",
"password":"123456"
}
- Js如何解析Json
JSON.parse(str)
- Js如何封装Json
var data = {
"account": "admin",
"password": "123456"
}
json = JSON.stringify(data)
Http
在了解学习xhr时,我们要对http协议具有基本的了解
HTTP协议
http协议为超文本传输协议,直白来说,就是用以传输所编写好网页的tcp协议,而tcp协议可以理解为传输二进制流数据的一种方式
http协议由客户端主动发起请求,服务端返回响应数据
请求
一次网页的打开,通过一次请求一次响应构成
请求方式
在传输的方式上,也分为了主要GET和POST等多种请求方式,现在只讨论GET、POST
其中GET请求非常常见,普通的浏览网页行为都是GET请求,也就是当输入连接在浏览器紧接着敲击键盘上的回车时
而POST常用在表单提交过程,比如用户的登录、注册这样的认证行为,起始就是一次POST请求,POST请求也被理解为提交数据的请求方式
当然,不管是GET还是POST,一次请求,就会带来一次响应,都是可以获取到数据的
| 请求 | 解释 |
|---|---|
| GET | 获取服务端数据; |
| POST | 向服务端提交数据; |
| PUT | 向服务端上传数据; |
| DELETE | 删除服务端通过Request-URL所标示的资源; |
| TRACE | 测试服务端是否可以接收到Request请求; |
| CONNECT | 以管道方式连接代理服务器; |
| OPTIONS | 返回服务器所支持的其他HTTP请求方法; |
| HEAD | 与GET方法类似,但不返回服务器响应时的消息体; |
请求头
我们看到的请求头,就是当我们通过浏览器访问一个URL时,会向服务器发送的,我们经常叫这个为Request Headers(请求头)
在请求头中,维护了很多字段信息,这些常见的HTTP请求头中响应字段的详细解释如下
通过这些头部字段的标识,可以让服务器清晰认识到自己应该给客户端提供的数据
| Accept: text/html | 指定客户端支持接收的数据类型(MIME类型)。 |
|---|---|
| Accept-Charset: utf-8 | 指定客户端可接受的字符集,缺省表示任何字符集都可以接受; |
| Accept-Encoding: gzip, deflate | 指定客户端支持的Web服务器返回内容压缩编码类型。 |
| Accept-Language: zh-CN | 指定客户端可以接受的语言; |
| Authorization:Basic xxx= | HTTP认证的权限; |
| Cache-Control: no-cache | 指定所有缓存机制必须遵从的指令; |
| Connection: keep-alive | 表示是否需要持久连接(HTTP1.1协议中默认进行持久连接); |
| Content-Length: 123 | 请求的内容长度; |
| Content-Type: text/html | 用于在post及put时请求的媒体类型; |
| Cookie: $XXX | 保存在该请求域名下的COOKIE值信息,常用于表示用户的历史访问记录; |
| Date: Tue, 15 Nov | 请求发送的日期时间; |
| Referer: … | 访问到这个站点之前的地址,用来指定访问从何处而来; |
| User-Agent: … | 指定当前访问者的用户信息,经常为一些浏览器、操作系统属性; |
响应
在http协议中,有很多传输数据的类型,被称作MIME格式,比如image/png专门用来标记描述被传输的数据为png格式的图片
状态码
http协议通过状态码标识此次请求是否成功或失败,失败了又是因为啥
| 状态码 | 状态码英文标示 | 意义 |
|---|---|---|
| 200 | OK | 客户端的请求服务端正常完成; |
| 301 | Moved Permanently | 客户端请求的资源已被永久移动到新的URL; |
| 302 | Found | 客户顿请求的资源被临时移动,客户端继续使用原有URL;常用于三方登录之后的跳转; |
| 400 | Bad Request | 客户端的请求语法错误,或无法解析请求; |
| 401 | Unauthorized | 请求需要经过身份验证; |
| 403 | Forbidden | 服务端直接拒绝客户端的请求; |
| 404 | Not Found | 客户端请求的资源找不到; |
| 405 | Method Not Allowed | 客户端请求的方式不被允许; |
| 500 | Internal Server Error | 服务端内部错误; 可能是因为Web服务配置文件读取错误 也可能是因为用户权限等等问题导致… |
| 502 | Bad Geteway | 服务端内部错误; 服务端错误的网关; |
响应头
通过相应的头部字段,可以表示标识返回数据的类型等等格式,让浏览器或接受数据的一方更好的解析服务器的返回
| Age: 775 | 从原始服务器到代理缓存形成的时间估算(秒为单位); |
|---|---|
| Allow: GET,HEAD | 指定资源的有效请求行为,不允许请求则返回405; |
| Cache-Control: max-age=3600 | 缓存机制,max-age参数未缓存有效时间(秒为单位); |
| Content-Encoding: gzip | 响应内容的支持的压缩编码类型 |
| Content-Disposition: attachment; filename="fname.ext" | 可下载资源属性(MIME二进制格式),提供文件下载的对话框,并默认文件名为filename; |
| Content-Length: 348 | 响应的数据长度; |
| Content-Language: en-US | 响应的数据语言格式; |
| Content-Location: /index.htm | 响应资源的替代地址; |
| Content-Type: text/html; charset=utf-8 | 响应数据的MIME类型; |
| Date: Tue, 15 Nov… | 服务器发送响应时的日期时间; |
| Expires: Tue, 15 Nov… | 响应过期的日期时间; |
| Server: Nginx | Web服务器名称; |
| Set-Cookie: username=test; Max-Age=3600; | 设置HTTP响应中的cookie值; |
数据提交格式
在使用post方式向服务端提交数据时,主要有如下四种提交数据的类型Content-Type
-
application/x-www-form-urlencoded: 浏览器原生表单 -
multipart/form-data: 表单上传文件时 -
application/json: 前后端分离,提交复杂格式化数据时 -
text/xml: 使用XML-RPC远程调用的请求数据类型
Mock xxx
为了模拟服务器返回数据,可以采用mock.js用来模拟服务器,用以返回数据;当然如果不嫌麻烦,起始自定义假数据也可以
- 安装
npm install mockjs
Xhr
参考地址: developer.mozilla.org/
基本流程
XMLHttpRequest是AJAX的基础,目前大多数主流浏览器都支持XMLHttpRequest的请求方式,简称XHR
- 创建
XHR对象
var xhr = new XMLHttpRequest(); // IE7+, Firefox, Chrome, Opera, Safari
var xhr = new ActiveXObject("Microsoft.XMLHTTP"); // IE6, IE5
- 初始化请求
xhr.open(method, url, async);
// method: 用于请求的HTTP方法,大小写不敏感
// url: 请求的主体
// async: 是否异步
如果不是异步的请求方式,那么响应获取结果只需要写到send方法之后即可
但如果是异步的方式,那么获取响应结果需要单独编写回调方法onreadystatechange获取,在下面的回调部分会有
- 设置头部
常用来设置Authorization头部,用以完成某些请求的身份认证工作
xhr.setRequestHeader(name, value)
// name: 设置头部名称,参数不包括空白、冒号或换行
// value: 参数是头部的值,参数不包括换行
- 发送请求
xhr.send()
请求属性
- 响应类型限定
通过该属性声明此时客户端希望得到服务端的数据类型,该属性为一个枚举类型
xhr.responseType
有如下可选设置,默认为text类型,也就是Js中的字符串
| 值 | 数据类型 |
|---|---|
| '' | DOMString |
arraybuffer | ArrayBuffer对象 |
blob | Blob对象 |
document | Document对象 |
json | Object对象 |
text | DOMString |
注意: responseType无法设置在一个同步请求上,给一个同步请求设置responseType会抛出一个InvalidAccessError的异常
- 响应状态获取
获取此次相应是否已经结束,还是刚刚开始
xhr.readyState
| 值 | 状态 | 状态说明 |
|---|---|---|
0 | UNSENT | 请求创建好之后,调用open之前 |
1 | OPENED | 调用open之后 |
2 | HEADERS_RECEIVED | 调用send之后 |
3 | LOADING | Downloading; responseText holds partial data. |
4 | DONE | 整个请求结束 |
整个XMLHttpRequest对象的生命周期应该如下阶段: UNSENT-初始化请求-发送请求-接收数据-解析数据-DONE
- 响应状态码获取
xhr.status
- 响应结果获取
xhr.responseText // 获取文本类型结果
xhr.responseXML // 获取xml格式结果
xhr.response // 获取到根据响应格式responseType对应解析好的数据
response属性会根据responseType设置的类型进行解析
请求回调
当请求成功发起时,此时会有一些回调方法可以获取到服务器的响应或是请求报错
onload: 请求成功
xhr.onload(e){}
onerror: 请求出错
xhr.onerror(){}
ontimeout: 请求超时
xhr.ontimeout(e){}
请求回调的事件方法定义,应该都处于xhr.send之前
请求示范
异步请求
如下是一个异步的请求demo
let xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.responseType = "json"
// 请求结束
xhr.onreadystatechange = e => {
if(xhr.readystate === 4 && xhr.status==200) {
let res = 'response' in xhr ? xhr.response : xhr.responseText
}
};
同步请求
如果是同步的请求,由于无法设置responseType,需要手动通过JSON.parse解析
var xhr = new XMLHttpRequest()
xhr.open("GET", "http://127.0.0.1:8000/", false)
xhr.onload = function () {
let response = xhr.response
let json_response = JSON.parse(response)
}
文件请求
json格式的文件也是可以请求的
window.onload = function () {
var xhr = new XMLHttpRequest()
url = 'xxx.json'
xhr.open("get",url)
xhr.onload= function(){
let response = JSON.parse(xhr.response)
}
xhr.send()
}
数据提交
一般的,使用xhr提交数据可以采用json或form-data两种方法,分别对应如下的数据初始化方法
// json
xhr.send(JSON.stringify());
// form-data
var formData = new FormData()
formData.append(key,v)
xhr.send(formData)
下面是一个提交包含文件及form-data数据提交的的小例子
<input id="file" onchange="getfile()" type="file" name="" id="">
<button onclick="send()">send</button>
var file;
function getfile() { // 获取文件
file = document.getElementById("file").files[0]
}
function send() {
if (!file){
return
}
var xhr = new XMLHttpRequest()
var formData = new FormData()
formData.append(key, v)
formData.append("file", file)
xhr.open("post", "http://127.0.0.1:8000")
xhr.onload = function () {
var response = xhr.response
}
xhr.send(formData) // 发送具有文件的表单数据
}
Ajax
jQuery库拥有完整的Ajax方法,可以在不刷新浏览器的情况下从服务器加载数据,并且使用起来比xhr更加的简单方便
请求属性
$.ajax({
url: "http://127.0.0.1:8000",
})
| 参数 | 解释 |
|---|---|
| async | 是否为异步请求,默认为true |
| url | 请求地址 |
| dataType | 预期的返回结果类型,前端会通过该属性对返回数据进行对应的解析 |
| contentType | 请求时,发送的数据类型,默认为application/x-www-form-urlencoded |
| processData | 通过请求发送的数据是否转换为查询字符串,默认是true |
| data | 经常在post请求时发送的数据 |
| error(xhr,status,error) | 回调方法,请求错误时调用 |
| success(result,status,xhr) | 回调方法,请求成功时调用 |
关于contentType,遵循MIME格式,可以选择如下常用的数据格式
| 提交格式 | 解释 |
|---|---|
application/x-www-form-urlencoded | 表单数据 |
multipart/form-data | 表单数据,常具有文件 |
application/json | json数据 |
关于dataType,有如下可选类型
| 类型选项 | 解释 |
|---|---|
| xml | xml文档 |
| html | 返回html文档信息,如果包含script代码,会在渲染至dom时执行 |
| json | json数据 |
| text | 文本数据 |
| local | 本地数据 |
请求回调
成功
success(result): 请求成功时调用
success: function (result,status) {
$("p").html(result.time)
},
result: 服务器返回的数据,会根据dataType指定的类型尝试解析status: 服务器返回的状态
失败
error(xhr, status, error): 请求错误时调用
error: function(xhr, status, error){
if(xhr.status==404){
console.log("路由不存在")
return
}
}
-
xhr: 该对象是一个超集,包括XMLHttpRequest对象,以及更多的详细属性和信息,比如请求失败的状态码等信息;内置的属性比较重要的有如下四个,经常会在开发过程中使用,完成一些状态判断的工作readyState: 当前状态,0-未初始化,1-正在载入,2-已经载入,3-数据进行交互,4-完成status: 返回的HTTP状态码,比如常见的404,500等错误代码statusText: 对应状态码的错误信息,比如404错误信息是not found,500是Internal Server ErrorresponseText: 服务器响应返回的文本信息
-
status: 返回的是字符串类型,表示返回的状态,根据服务器不同的错误可能返回下面这些信息timeout: 超时error: 错误abort: 中止parsererror: 解析错误- 还有可能返回空值
-
error:字符串类型,表示服务器抛出返回的错误信息,如果产生的是HTTP错误,那么返回的信息就是HTTP状态码对应的错误信息,比如404的Not Found,500错误的Internal Server Error
请求示范
GET
请求接口数据的一个示范
$.ajax({
url: "http://127.0.0.1:8000",
type: "get",
dataType: "json",
success: function (result) {
...
},
error: function (xhr, result, error) {
...
}
})
jquery的ajax还支持更方便的get请求方法
$.get(url,data,success(response,status,xhr),dataType)
POST
提交json格式的数据
$.ajax({
url: "http://127.0.0.1:8000",
type: "post",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"account": "123",
}),
success: function (result) {
...
},
error: function (xhr, result, error) {
...
}
})
jquery的ajax还支持更方便的post请求方法
$.post(url,data,success(data, textStatus, jqXHR),dataType)
上传文件
<input id="file" onchange="getfile()" type="file" name="" id="">
<button onclick="send()">send</button>
功能方法,在input文件输入框触发选择文件时,保留当前表单的文件对象到全局变量file中
var file;
function getfile() {
file = document.getElementById("file").files[0]
}
当点击send按钮时,提交文件及其他数据
function send() {
var formData = new FormData()
formData.append("file", file)
formData.append("account", "123")
$.ajax({
url: "http://127.0.0.1:8000/",
type: "post",
dataType: "json",
contentType: false,
processData: false,
data: formData,
success: function (result) {},
error: function (xhr, result, error) {}
})
}
注意: 一定要加contentType: false,processData: false这两个配置,这是为了避开jQuery对于Content-Type的设置,让XMLHttpRequest对form-data进行正确的处理
这也是因为发送文件时,文件的内容和文本的内容需要分隔开,不然服务器没有办法正常的解析文件
对于上传文件的请求,contentType=multipart/form-data是必须的
在文件的数据提交部分,会有后面有boundary以及一串字符,这是分界符,后面的一堆字符串是随机生成的,目的是防止上传文件中出现分界符导致服务器无法正确识别文件起始位置
而设置contentType 为false是为了避免 JQuery对其操作,从而失去分界符,而使服务器不能正常解析文件
注意
在ajax上传文时,获取文件使用jquery的dom操作
那么应该
$('#health_code')[0].files[0]