AJAX
定义:Ajax 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求)。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
同步:必须等待前面的任务完成,才能继续后面的任务。
异步:不受当前任务的影响。
(一)五大步骤
-
1、创建XMLHttpRequest对象,也就是创建一个异步调用对象.
var xmlhttp = new XMLHttpRequest();
-
2、创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
/* * 规定请求的类型、URL 以及是否异步处理请求。 * open(method,url,async) * method:请求的类型;GET 或 POST * url:文件在服务器上的位置 * async:true(异步)或 false(同步) */ 例://get方式 xmlhttp.open("GET","ajax_info.txt",true); //post方式发送数据需要设置请求头 xmlhttp.open("post","test.php",true) xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
get和post(Http两种协议,基于TCP协议)
- GET产生一个TCP数据包;POST产生两个TCP数据包。
- 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
- 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。通俗一点说:post请求的好比是看客户端发送请求前先告诉服务端即将发起请求,服务端告知客户端可以请求,客户端再将请求的信息带到服务端去
- Post:post请求的参数会放到request body中,参数传递更加的安全,同时post支持多种编码方式。
- Get:请求的参数通过url传递,并且url的长度有限制,相对于Post而言更加不安全(参数直接暴露在url中), get请求的内容浏览器会自动的缓存
get的url:https://baijiahao.baidu.com/s? id=1626599028653203490&wfr=spider&for=pc
- GET产生一个TCP数据包;POST产生两个TCP数据包。
-
3、发送HTTP请求
XMLHttpRequest.send(data); //data是个可选参数
-
4、设置响应HTTP请求状态变化的函数,并设置获取服务器返回数据的语句
XMLHttpRequest5种状态
发送HTTP请求的目的是为了接收从服务器中返回的数据。从创建XMLHttpRequest对象开始,到发送数据、接收数据、XMLHttpRequest对象一共会经历以下5种状态。
- 0:未初始化状态。在创建完XMLHttpRequest对象时,该对象处于未初始化状态。
- 1:初始化状态。在创建完XMLHttpRequest对象后使用open()方法创建了HTTP请求时,该对象处于初始化状态,还没有调用send()
- 2:发送数据状态。在初始化XMLHttpRequest对象后,使用send()方法发送数据时,该对象处于发送数据状态。
- 3:接收数据状态。Web服务器接收完数据并进行处理完毕之后,向客户端传送返回的结果。此时,XMLHttpRequest对象处于接收数据状态。
- 4:完成状态。XMLHttpRequest对象接收数据完毕后,进入完成状态,此时XMLHttpRequest对象的readyState属性值为4。此时接收完毕后的数据存入在客户端计算机的内存中,可以使用responseText属性或responseXml属性来获取数据。
只有在XMLHttpRequest对象完成了以上5个步骤之后,才可以获取从服务器端返回的数据。因此,如果要获得从服务器端返回的数据,就必须要先判断XMLHttpRequest对象的状态。
Http状态码
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求
200: 请求成功;
301: 当前请求的资源已被永久的移动到新的URI,返回的信息通常包含新的URI地址.
304: 所请求的资源未被修改,服务器返回状态码,不返回任何资源。客户端通常会缓存过访问的资源。
305: 当前请求的资源必须要通过代理进行访问
400: 客户端请求语法错误,服务端无法理解信息;
401: 请求要求用户完成认证,授权失败
403: 服务器拒绝执行当前请求;
404: 服务器无法根据用户请求找到相应的资源,没有发现文件、查询或URl
405: 客户端发起请求的方式被禁止;
410: 客户端请求的资源已经不存在;
415: 服务器无法处理请求附带的媒体格式;
500: 服务器内部错误;
501: 服务器不支持请求功能,无法完成请求;
503——服务器过载或暂停维修
505: 服务器不支持请求的Http协议的版本,无法完成请求;
当 readyState 等于 4 且状态为 200 时,表示响应已就绪
xmlHttpRequest.onreadystatechange = getData; //定义函数 function getData() { //判断XMLHttpRequest对象的readyState属性值是否为4,如果为4表示异步调用完成 if (xmlHttpRequest.readyState == 4) { //如果HTML文件不是在Web服务器上运行,而是在本地运行,则xmlHttpRequest.status的返回值为0。因此,如果该文件在本地运行,则应该加上xmlHttpRequest.status == 0的判断 if (xmlHttpRequest.status == 200 || xmlHttpRequest.status == 0) { document.write(xmlHttpRequest.responseText); //将返回结果以字符串形式输出 } } }
-
5、获取返回的数据.
(二)代码:
1、get传递参数
var xhr = new XMLHttpRequest();
xhr.open("get", "http://localhost:3000/top/album?offset=0&limit=3",true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {
console.log(xhr.responseText);
}
}
//jquery
$.ajax({
url:'http://localhost:3000/top/album?offset=0&limit=3',
type:'GET',
dataType: 'json',
success:function(data) {
console.log(data);
}
})
2、post传递参数
var xhr = new XMLHttpRequest();
xhr.open("post",
"http://localhost:3000/top/album",
true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(`offset=0&limit=3`);
xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {
console.log(xhr.responseText);
}
}
var xhr = new XMLHttpRequest();
var data = {
'offset': 0,
'limit': 3
}
data = (function (obj) { // 转成post需要的字符串.
var str = "";
for (var prop in obj) {
str += prop + "=" + obj[prop] + "&"
}
return str;
})(data);
xhr.open("post",
"http://localhost:3000/top/album",
true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//data: offset=0&limit=3
console.log(data)
xhr.send(data);
xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {
console.log(xhr.responseText);
}
}
//jquery
$.ajax({
url: 'http://localhost:3000/top/album',
type: 'POST',
dataType: 'json',
data: {
offset: 0,
limit: 3
},
success: function (res) {
console.log(res);
},
error: function (rej) {
console.log(rej)
}
})
3、自己封装ajax方法
function ajax(options) {
//存储默认值
var defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function () {},
error: function () {}
}
//使用options对象中的属性覆盖defaults对象中的属性
Object.assign(defaults, options);
var xhr = new XMLHttpRequest();
var params = '';
//循环用户传递进来的对象格式参数
for (var attr in defaults.data) {
//将参数转化为字符串格式
params += attr + '=' + defaults.data[attr] + '&'
}
//将参数最后的&截取掉
params = params.substr(0, params.length - 1)
//判断请求方式
if (defaults.type == 'get') {
defaults.url = defaults.url + '?' + params
}
xhr.open(defaults.type, defaults.url);
//如果请求方式为post
if (defaults.type == 'post') {
//请求参数类型
var ContentType = defaults.header['Content-Type']
xhr.setRequestHeader('Content-Type', ContentType);
if (ContentType == 'application/json') {
//传递json数据格式
xhr.send(JSON.stringify(defaults.data))
} else {
//传递字符串拼接格式
xhr.send(params)
}
} else {
xhr.send();
}
xhr.onload = function () {
//获取响应头数据
var contenTtype = xhr.getResponseHeader('Content-Type')
//服务器端返回的数据
var responseText = xhr.responseText
//判断是否包含application/json
if (contenTtype.includes('application/json')) {
//将json字符串转化为json对象
responseText = JSON.parse(responseText)
}
//判断是否成功
if (xhr.status == 200) {
defaults.success(responseText, xhr);
} else {
defaults.error(responseText, xhr)
}
}
}
//get方式
ajax({
url: 'http://localhost:3000/top/album?offset=0&limit=3',
type: 'GET',
dataType: 'json',
success: function (data, xhr) {
console.log(data, xhr)
},
})
//post方式
ajax({
url: 'http://localhost:3000/top/album',
type: 'POST',
data: {
offset: 0,
limit: 3
},
dataType: 'json',
success: function (data, xhr) {
console.log(data, xhr)
},
})
4、对数据的操作
<div class="container">
<p id="list"></p>
</div>
var xhr = new XMLHttpRequest();
xhr.open("get",
"http://localhost:3000/search/hot",
true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {
var res = xhr.responseText;
// 将res转换为json对象
var lists = eval("(" + res + ")").result.hots;
var data =(new Function("","return "+res))();
console.log(lists)
for (i = 0; i < 10; i++) {
var dom = `<div class="songname">${lists[i].first}</div>`
$("#list").append(dom)
}
}
}
//jquery
$.ajax({
url: 'http://localhost:3000/top/album?offset=0&limit=3',
type: 'GET',
dataType: 'json',
success: function (result) {
var lists = result.monthData;
for (i = 0; i < 10; i++) {
console.log(lists[i].name);
dom = `<div class = "songname">${lists[i].name}</div>`
$("#list").append(dom)
}
}
})