自己的一些理解
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
简单说就是ajax就是一套可以让网站跟服务器交互的一种技术,能在我们需要时,不用再刷新网页就能去服务器要一些数据回来
为什么需要ajax
在不刷新页面的情况下向服务器请求数据
1、之前我们写的页面都是固定的假数据
2、真实网站的数据都是从服务器读取出来,服务器数据一旦改变,网站上显示的内容就发生改变
3、虽然可以通过直接输入URL的方式向服务器获取数据,但是页面会刷新
4、学会ajax就可以在不刷新页面的情况下向服务器请求数据,让网站内容动态改变
Ajax基本使用
基本使用-get请求
ajax使用步骤:
1、创建xhr对象
2、初始化请求
3、发送请求
4、注册onload事件,拿到服务器给你的结果
//1. 创建xhr对象
var xhr = new XMLHttpRequest();
//2. 初始化请求
xhr.open('get',服务器地址);
//3. 发送请求
xhr.send();
//4. 注册onload事件,拿到服务器给你的结果
xhr.onload = function(){
console.log(xhr.responseText);
}
初始化请求,我们用open
方法,参数1现在就写死get
,他叫做请求方法,参数2代表你要请求的服务器路径(网络上那么多资源,你得给个路径告诉它找哪个对不?)
第二步初始化请求你可以理解为是打电话中的输入号码那一步,第三步发送请求你可以理解为就相当于是按下了拨号键
基本使用-post请求
跟get请求步骤都是一样的,但是在初始化请求完成后(也即open方法后)要多设置一行请求头
//1. 创建xhr对象
var xhr = new XMLHttpRequest();
//2. 初始化请求
xhr.open('post',服务器地址);
//3. 设置请求头
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
//4. 发送请求
xhr.send('提交给服务器数据');
//5. 监听响应的回调函数
xhr.onload = function(){
console.log(xhr.responseText);
}
如果不需要给服务器提交数据,则send方法里什么都不写,或者写null或者写undefined都可以
如果需要给服务器提交数据,依然是用 key=value 的格式
// 一条数据
xhr.send('key=value')
// 多条数据
xhr.send('key1=value1value2')
// 没有数据 下面三种都可以
xhr.send()
xhr.send(null)
xhr.send(undefined)
对于不同的请求方式数据传递的方式不同:
-
get请求直接拼接在url的后面:
url?key=valuevalue2
-
post请求,通过send方法传递
xhr.send('key1=value2value2')
为什么方法和地址不同,甚至还需要传递数据过去呢?这是因为我们在请求不同的接口
什么是接口
我们在使用Ajax请求数据时,请求的地址不是随便写的,是对应的服务器地址。服务器提供给我们请求的这个地址,我们可以把它叫做接口,向接口对应的地址发请求获取数据,可以称为调用接口
我们在调用接口时,必须得知道的内容有3个
1、接口地址
2、请求方法
3、参数
看接口文档开发
既然服务器代码不是我们写的, 是后端开发人员写的。那么我们怎么知道请求的地址、方式、参数是什么呢?
实际开发中,会提供一个接口文档,接口文档是一个最起码包含了请求方式、请求路径、请求参数的接口使用说明书
jQuery 中封装的 AJAX
jQuery 中有一套专门针对 AJAX 的封装,功能十分完善,经常使用
$.ajax({
url: '/time',
type: 'get',
dataType: 'json',
data: { id: 1 },
beforeSend: function (xhr) {
console.log('before send')
},
success: function (data) {
console.log(data)
},
error: function (xhr) {
console.log(xhr)
},
complete: function (xhr) {
console.log('request completed')
}
})
常用选项参数介绍:
cache: 设置ie浏览器的缓存问题, cache: false 不缓存
url:请求地址
type / method:请求方法,默认为 get
dataType:预期服务端响应数据类型
contentType:请求体内容类型,默认 application/x-www-form-urlencoded
data:需要传递到服务端的数据,如果 GET 则通过 URL 传递,如果 POST 则通过请求体传递
timeout:请求超时时间
beforeSend:请求发起之前触发
success:请求成功之后触发(响应状态码 200)
error:请求失败触发
complete:请求完成触发(不管成功与否)
jQuery封装的发送Ajax请求的快捷方法
GET 请求快捷方法
$.get(url, [data], [callback], [dataType])
$.get({settings})
POST 请求快捷方法
$.post(url, [data], [callback], [dataType])
$.post({settings})
全局事件处理
每次Ajax请求都需要的事件,比如给一个请求响应过程进度提示,可以使用全局事件处理。反过来说,通过全局事件处理的事件,后续的每个ajax请求都会触发。
$.ajaxSetup({事件: 处理函数, 事件:处理函数, ...});
示例:
// 设置全局事件处理
$.ajaxSetup({
// 设置发送请求前的事件
beforeSend: function () {
// 这里可以提示,玩命加载中...
},
// 设置完全接收响应数据后的事件
complete: function () {
// 这里可以去掉“玩命加载中...”
}
});
参考链接:http://www.jquery123.com/category/ajax/global-ajax-event-handlers/
其他封装库Axios(先了解,后续我会细说)
Axios 是目前应用最为广泛的 AJAX 封装库,相对于 jQuery 的优势在于功能能强劲,职责更单一
axios
.get('http://rap2api.taobao.org/app/mock/23080/resources/search',{
params: {
id: 5
}
})
.then(res => {
console.log('数据是:', res);
})
.catch((e) => {
console.log('获取数据失败');
});
axios({
url: 'http://rap2api.taobao.org/app/mock/121145/post',
method: 'post',
data: {
name: 'zs'
}
}).then(res => {
console.log('请求结果:', res);
});
感兴趣可以参考:GitHub - axios/axios: Promise based HTTP client for the browser and node.js
XMLHttpRequest 2.0
HTML5 中对 XMLHttpRequest 类型全面升级,更易用,更强大
responseType / response
-
responseType -- 预期服务器返回数据的类型
-
“” -- 空,表示文本,和text一样。空为默认值
-
text -- 文本
-
json -- JSON格式数据
-
document -- 文档对象
-
-
response -- 根据responseType的值自动处理返回结果,可以接收任何类型的结果
onload / onprogress
var xhr = new XMLHttpRequest()
xhr.open('GET', '/time')
xhr.onload = function () {
// onload readyState => 4
// 只在请求完成时触发
console.log(this.readyState)
}
xhr.onprogress = function () {
// onprogress readyState => 3
// 只在请求进行中触发
console.log(this.readyState)
}
xhr.send(null)
FormData是h5中新增的一个内置对象。
FormData对象用以将数据编译成键值对,以便用XMLHttpRequest
来发送数据。其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。
以前 AJAX 操作只能提交字符串,现在可以提交 二进制 的数据
使用方法一(有form表单)
<form id="fm">
<input type="text" name="user"><br>
<input type="password" name="pwd"><br>
<input type="radio" name="sex" value="男" checked>男
<input type="radio" name="sex" value="女">女<br>
<input type="file" name="pic"><br/>
<input type="button" id="btn" value="提交">
</form>
<script>
// 点击按钮的时候,收集表单中的数据,并发送给服务器
document.getElementById('btn').onclick = function () {
// 使用FormData步骤1:找到表单
var fm = document.getElementById('fm');
// 使用FormData步骤2:创建FormData对象,并传递表单
var fd = new FormData(fm);
// 发送ajax请求到服务器
var xhr = new XMLHttpRequest();
xhr.open('POST', '/fd'); // 接口fd,收到提交的数据后,会返回收到的数据
// 使用FormData收集表单数据的时候,Content-Type不用设置
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(fd);
xhr.onload = function () {
console.log(this.response);
};
};
</script>
使用方法二(没有form表单)
<input type="text" id="user"><br>
<input type="password" id="pwd"><br>
<input type="file" id="pic"><br/>
<input type="button" id="btn" value="提交">
<script>
// 点击按钮的时候,收集表单中的数据,并发送给服务器
document.getElementById('btn').onclick = function () {
// 没有表单,只能先实例化FormData
var fd = new FormData(fm);
// 调用FormData对象中的方法,向对象中添加数据
fd.append("username", document.getElementById('user').value);
fd.append("pwd", document.getElementById('pwd').value);
// HTML 文件类型input,由用户选择
fd.append("userfile", document.getElementById('pic').files[0]);
// 发送ajax请求到服务器
var xhr = new XMLHttpRequest();
xhr.open('POST', '/fd'); // 接口fd,收到提交的数据后,会返回收到的数据
// 使用FormData收集表单数据的时候,Content-Type不用设置
xhr.send(fd);
xhr.onload = function () {
console.log(this.response);
};
};
</script>
jQuery中使用FormData:
<form id="fm">
<input type="text" name="user"><br>
<input type="password" name="pwd"><br>
<input type="radio" name="sex" value="男" checked>男
<input type="radio" name="sex" value="女">女<br>
<input type="file" name="pic"><br />
<input type="button" id="btn" value="提交">
</form>
<script src="/jquery.js"></script>
<script>
$('#btn').click(function () {
var fm = $('#fm');
var fd = new FormData(fm[0]); // 这里fm必须是DOM对象
console.log(fd);
$.ajax({
type: 'post',
url: '/fd',
// 如果data使用的是对象,ajax方法会把对象转成字符串,
// 即把{name: 'zs', age: 18}转成name=zs18
// data: {name: 'zs', age: 18},
data: fd,
// processData: false, 表示不让jQuery把fd对象转成字符串,而是直接发送fd对象
processData: false,
// contentType:false,表示不让jQuery去设置content-type,让FormData去处理
contentType: false,
success: function (res) {
console.log(res);
}
});
});
// xhr.send('name=zs18');
</script>
AJAX 补充
onreadystatechange
-
onload 是 HTML5 以后新增的方便获取响应的事件
-
过去获取浏览器返回内容的时候使用的是 onreadystatechange
在通过Ajax向服务器发送请求的过程中,XMLHttpRequest
对象的状态会发生多次变化。由于 readystatechange
事件是在 xhr
对象状态变化时触发(不单是在得到响应时),也就意味着这个事件会被触发多次
-
xhr
对象的状态-
有5种
-
用readyState属性表示,详见下表
-
readyState | 状态描述 | 说明 |
---|---|---|
0 | UNSENT | 代理(XHR)被创建,但尚未调用 open() 方法。 |
1 | OPENED | open() 方法已经被调用,建立了连接。 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且已经可以获取状态行和响应头。 |
3 | LOADING | 响应体下载中, responseText 属性可能已经包含部分数据。 |
4 | DONE | 响应体下载完成,可以直接使用 responseText 。 |
同步与异步
关于同步与异步的概念在生活中有很多常见的场景,举例说明。
*同步:一个人在同一个时刻只能做一件事情,在执行一些耗时的操作(不需要看管)不去做别的事,只是等待
*异步:在执行一些耗时的操作(不需要看管)去做别的事,而不是等待
xhr.open()
方法第三个参数要求传入的是一个 bool
值,其作用就是设置此次请求是否采用异步方式执行,默认为 true
,如果需要同步执行可以通过传递 false
实现
XMLHttpRequest API 总结
属性
-
readyState
xhr的状态 4 响应体接收完毕 -
status
获取状态码 -
responseText
获取响应体,文本格式 -
responseXML
获取响应体,xml格式 -
onreadystatechange
事件,当xhr.readyState属性发生改变触发 -
onload
事件,响应接收完毕
方法
-
open(method, url, async)
设置请求的方式,请求的路径, 同步/异步 -
send(requsetBody)
发送请求(体) -
setRequestHeader(key, value)
设置请求头 -
getResponseHeader(key)
获取响应头