ajax详解,四种方式发送ajax请求
ajax简介:ajax全称为Asynchronous JavaScript And XML,就是异步的JS和XML
通过ajax可以在浏览器中向服务器发送异步请求,然后浏览器处理后返回请求内容
最大的优势 : 无刷新获取数据,
ajax不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
ajax的优点
1 . 可以无需刷新页面与服务器端进行通信
2 . 允许根据用户事件来更新不分页面的内容
ajax的缺点
1 . 没有浏览历史,不能回退
2 . 存在跨域问题
3 . SEO(搜索引擎优化)不友好,爬虫爬不到
那么我们也要知道什么是XML
XML :
XML 指可扩展标记语言
XML 被设计用来传输和存储数据 (重要)
XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,
全都是自定义标签,用来表示一些数据。
(最开始ajax返回的数据就是XML字符串,不过现在基本都是JSON格式进行传输)
<!-- 这是html标签 -->
<student name="孙悟空";age="18";gneder="男"></student>
<!-- 这是xml标签 -->
<student>
<name>孙悟空</name>
<age>18</age>
<gneder>男</gneder>
</student>
在学习ajax之前我们还不得不了解一下HTTP协议
HTTP (hypertext transport protocol) ,即超文本传输协议。这个协议详细规定了浏览器和万维网服务器之间互相通信的规则
何为协议?简单一点说就是一种约束,规则,服务器和客户端都要遵守的规则
HTTP就是一个通信规则,通信规则规定了客户端发送给服务器的内容格式,也规定了服务器发送给客户端的内容格式。其实我们要学习的就是这个两个格式!
客户端发送给服务器的格式叫 "请求协议;
服务器发送给客户端的格式叫 “响应协议”。
请求的内容还有一个专业名词,叫做:“请求报文”
相应的内容也有一个专业名词,叫做:"响应报文"
请求报文的格式和参数(包括四部分):
1 .(请求)行:
请求行包括 三 部分:
(第一部分:请求类型):GET、POST、PUT…
(第二部分:url路径):一个完整的url路径又分为这几个部分:
[ 协议名(http)域名(www.baidu.com)端口(80)请求文件(index.html)]
[ http://www.baidu.com:80 ]
(第三部分:http协议的版本): 如 [ 1.1版本(使用最多),1.0版本,2.0版本 ]
2 .(请求)头:
固定的格式内容(都是 key: value),这部分内容太多了
3 . 空行:(固定格式,必须得有的)
4 .(请求)体:(可以有内容,也可以没有内容)
如果是GET请求,请求体是空的
如果是POST请求,请求体可以不为空(如:name=tom&password=123)
"响应" 报文的格式和参数(也包括四部分):
1 .(响应)行:
响应 行包括 三 部分:
(第一部分:HTTP版本):HTTP/1.1
(第二部分:响应状态码):200、404…
(第三部分:响应字符串):ok(与状态码对应)
2 .(响应)头:固定的格式内容(都是 key: value),这部分内容太多了
3 . 空行:(固定格式,必须得有的)
4 .(响应)体:
1. 利用原生ajax,创建ajax请求
(最简单的一个原生ajax请求,所有内容均为最理想状态,不考虑任何网络和服务器因素)
var xhr = new XMLHttpRequest();
xhr.open("GET","https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata")
xhr.send();
xhr.onreadystatechange = callBack;
function callBack(){
if(xhr.status === 200 && xhr.readyState ===4){
console.log(xhr.response)
}
}
ajax详解,比较详细解释每一步的作用
// 第一步,创建xhr对象
var xhr = new XMLHttpRequest();
// 第二步,初始化,这是请求的方式,url,异步还是同步请求
// 最后一个参数true和false表示同步还是异步,true表示异步,默认为true,false表示同步
xhr.open("GET", "https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata", true)
/*
GET形式传递参数的请求,在URL的最后加上?和要传递的参数,多个参数之间用&连接
xhr.open("GET", "https://www.baidu.com/s?wd=鬼灭之刃", true)
*/
/*
如果是post传递参数的请求,要在send中传递参数
xhr.send("name=zhangsan&age=14")
xhr.send("name:zhangsan&age:14")
*/
// 设置请求头信息,接收两个参数,第一个是请求的名字,第二个是请求的值
// Content-Type用来设置请求体内容的类型,后面的参数值是固定写法,参数查询字符串的类型
// setRequestHeader可以添加预定的请求头,也可以添加自定义的
xhr.setRequestHeader("Content-Type","application/x-www-from-urlencoded")
// 设置响应体数据的类型,也就是返回回来的数据
xhr.responseType='json'
// 第三步,发送请求
xhr.send()
// 第四步,设置处理返回结果的回调函数
xhr.onreadystatechange = callBack;
function callBack() {
// readyState有五个值,分别是0 1 2 3 4
// 0 表示未初始化,最开始属性的值就是0
// 1 表示open方法调用完毕,
// 2 表示send方法调用完毕
// 3 表示服务端返回了部分结果
// 4 表示服务端返回了全部结果
// status 表示状态码
if (xhr.readyState === 4 && xhr.status === 200) {
// 满足条件后,处理数据,行、头、空行、体
// 1.响应行
console.log("响应状态码:" + xhr.status) //状态码
console.log("状态字符串:" + xhr.statusText) //状态字符串
// 2.响应头
console.log("响应头的所有内容:" + xhr.getAllResponseHeaders) //响应头的所有内容
// 3.响应体,一般都是拿响应体
console.log("响应体:" + xhr.responseText)
}
}
ajax请求超时与网络异常的处理
var xhr = new XMLHttpRequest();
// 请求超时设置,如果请求超过两秒钟,服务器还没有返回数据,就会取消这次请求
xhr.timeout = 2000;
// 请求超时还有一个回调函数
xhr.ontimeout = function(){
alert("请求超时,请稍后重试")
}
// 网络异常的回调函数
xhr.onerror = function(){
alert("无网络,请检查您的网络是否开启")
}
xhr.open("GET","https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata")
xhr.send();
xhr.onreadystatechange = callBack;
function callBack(){
if(xhr.status === 200 && xhr.readyState ===4){
console.log(xhr.response)
}
}
ajax处理重复发送请求问题,用户一直点击一直发送请求会给服务器造成巨大压力,这里设置在没有成功返回数据之前,如果用户还在发送请求,则取消上一次请求
<button id="btn">点击发送ajax请求</button>
<script>
var btn = document.getElementById('btn');
// 在前面先定义xhr,要不然下面的xhr.abort会出现未定义的情况
var xhr = null;
// 设置一个标识变量,表示是否在发送请求
// 初始值为false,当开始发送请求时,变为true,接收完数据后再次变成false
let isSending = false;
btn.addEventListener("click", function () {
if (isSending === true) {
// isSending === true 时表示,正在发送请求
// xhr.abort()方法可以手动取消请求
xhr.abort();
}
xhr = new XMLHttpRequest();
// 创建ajax请求了,修改标识变量的值
isSending = true
xhr.open("GET", "https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata")
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 当全部都加载完成后,设置isSending = false
// 切记不能在xhr.status === 200和xhr.readyState === 4都满足的情况下设置为false
// 因为会有请求失败的情况,也就是说xhr.status !== 200的情况
isSending = false
if (xhr.status === 200) {
console.log(xhr.response)
}
}
};
})
</script>
2 . 使用jQuery封装的ajax(使用jQuery时注意把文件路径引入script标签中)
<button id="btn">点击发送ajax请求</button>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
// jquery中的ajax请求
// get的请求方法(一般用来获取数据),可以添加参数,但是没必要
// 第一个参数为url地址,第二个参数为一个无论成功还是失败都会执行的回调函数,第三个参数为设置响应体的数据类型'json'
// 回调函数里的参数,parmas1表示的是请求返回的数据
// parmas2 不管成功还是失败都返回success
// parmas3 表示xhr对象
$.get("https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata",function(data,status,result){
console.log(data)
console.log(status)
console.log(result)
},'json')
// post会比get多一个参数,也就是要传递给服务器的参数,post一般是用来发送请求
var data = {
name:"zhangsan",
age:"24"
}
$.post("https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata",data,function (data) {
console.log(data)
})
})
</script>
3 . 使用axios封装的ajax(使用axios时注意把文件路径引入script标签中)
<button id="getBtn">GET</button>
<button id="postBtn">POST</button>
<button id="ajaxBtn">axios.all处理并发请求</button>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.js"></script>
<script>
var getBtn = document.getElementById("getBtn")
var postBtn = document.getElementById("postBtn")
var ajaxBtn = document.getElementById("ajaxBtn")
getBtn.addEventListener("click", function () {
// 几乎和jQuery一样,第一个参数为url,第二个参数{params:{}}要传递的参数
axios.get("https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata",
{
params: {
name: "zhangsan",
age: "24"
}
})
.then(function (data) {
console.log(data)
})
})
postBtn.addEventListener("click", function () {
// post没什么好说的,基本都一样
axios.post("https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata",
{
params: {
name: "zhangsan",
age: "24"
}
})
.then((v) => {
console.log(v)
})
})
axios.all解决并发请求
ajaxBtn.addEventListener("click", function () {
// axios.all
function getInfo() {
let obj = {
swiper: axios.get("https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata"),
logo: axios.get("https://api-hmugo-web.itheima.net/api/public/v1/home/catitems")
}
return obj;
}
axios.all([getInfo().swiper, getInfo().logo])
// 返回的参数为一个数组集合
.then((v) => {
console.log(v)
console.log(v[0])
console.log(v[1])
console.log("两个请求都加载好了")
})
})
4 . fetch函数实现ajax,fetch是自带的,不需要导入任何外部链接,但是用的比较少,见到能认识就OK
var getBtn = document.getElementById("getBtn")
getBtn.addEventListener("click",function(){
fetch("https://api-hmugo-web.itheima.net/api/public/v1/home/catitems",{
method:"GET"
}).then((v)=>{
return v.text();
}).then((v)=>{
console.log(v)
})
})