目录
一、Ajax简介
Ajax全称为Asynchhronous JavaScript And XML,就是异步的JS和XML。
通过Ajax可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据
Ajax不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
二、XML简介
(1)XML可扩展标记语言
(2)XML被设计用来传输和存储数据(html负责将数据呈现在页面上)
(3)XML与HTML类似,不同的是HTML中都是预定义标签(已经提前被定义好的),而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。(现在已经被JSON代替了)
//XML表示
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
//JSON表示
{"name":"孙悟空","age":18,"gender":"男"}
三、 AJAX的特点
1. AJAX的优点
1)可以无需刷新页面而与服务器端进行通信。
2)允许你根据用户事件来更新部分页面内容。
1.3.2 AJAX的缺点
1)没有浏览历史,不能回退
2)存 在跨域问题(同源)
3)SEO(Search Engine Optimization:搜索引擎优化)不友好
四、HTTP协议请求报文与响应报文结构
HTTP (hypertext transport protocol) 协议「超文本传输协议」,协议详细规定了浏览器和万维网服务器之间互相通信的规则。
请求报文:浏览器给服务器发送的内容
响应报文:服务器返回的结果
1.请求报文
行 请求类型(有GET/POST等) URL路径 HTTP协议版本(如:HTTP/1.1)
头 名字:(空格) 值, 如:
Host: baidu.com
Cookie: name=guigu
Content-type: applicat ion/ x -www-form-urlencoded
User-Agent: chrome 83空行
体 (可有内容也可没有,如果是GET请求,请求体是空的;POST请求体可以不为空,如 username=admin&password=admin)
2.响应报文
行 HTTP协议版本(如:HTTP/1.1) 响应状态码(如200) 响应字符串(OK)
(如200表示ok;404:找不到;401:未授权;500:内部错误)
头 Content- Type: text/html ; charset=utf-8
Content -length: 2048
Content- encoding: gzip空行
体 <html>
<head>
</head>
<body>
<h1>百度</h1>
</body>
</html>
五、express
//引入express
const express=require('express');
//创建应用对象
const app=express();
//创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/',(request,response)=>{
//设置响应
response.send("HELLO EXPRESS");
});
//监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中...");
})
六、get、post请求报文设置与服务器端
(get.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX GET请求</title>
<style>
#result{
width:200px;
height:100px;
border: aqua solid 1px;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
//获取button元素
const btn=document.getElementsByTagName('button')[0];
const result=document.getElementById("result");
//绑定事件
btn.onclick=function(){
//1.创建对象
//XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据
const xhr=new XMLHttpRequest();
//2.初始化 设置请求方法和url
xhr.open('Get','http://127.0.0.1:8000/server?a=100&b=200');
//3.发送
xhr.send();
//4.事件绑定 处理服务端返回的结果
//on 当...的时候
//readyState 是xhr对象中的属性,表示状态0(未初始化) 1(初始化) 2(发送) 3(服务器返回部分结果) 4(服务器返回全部结果)
//change改变
xhr.onreadystatechange=function(){
//判断(服务端返回了所有的结果)
if(xhr.readyState==4){
//判断响应状态码200 404 403 401 500
//2xx成功
if(xhr.status>=200&&xhr.status<300){
//处理结果:行 头 空行 体
//1.响应行
/* console.log(xhr.status);//状态码
console.log(xhr.statusText);//状态字符串
console.log(xhr.getAllResponseHeaders());//所有响应头
console.log(xhr.response);//响应体
*/
result.innerHTML=xhr.response;
}
}
}
}
</script>
</body>
</html>
(post.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX POST请求</title>
<style>
#result{
width:200px;
height:100px;
border:solid 1px #903;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
const result=document.getElementById("result");
result.addEventListener("mouseover",function(){
//1.创建对象
const xhr=new XMLHttpRequest();
//2.初始化 设置类型与URL
xhr.open('POST','http://127.0.0.1:8000/server');
//设置请求头 请求体类型 参数查询字符串的类型(固定写法)
xhr.setRequestHeader('Cotent-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','atbaidu');//自定义
//3.发送
xhr. send('a=100&b=200&c=300' ) ;
// xhr.send('1233211234567') ;
//xhr.send('a:100&b:200&c:300') ;
//4.事件绑定 处理服务端返回的结果
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300){
//处理服务器端返回的结果
result.innerHTML=xhr.response;
}
}
}
});
</script>
</body>
</html>
服务器端:
//引入express
const express=require('express');
//创建应用对象
const app=express();
//创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
//设置响应头 (此处设置允许跨域)
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send("HELLO AJAX");
})
/*app.post('/server',(request,response)=>{
//设置响应头 (此处设置允许跨域)
response.setHeader('Access-Control-Allow-Origin','*');
//响应头
response.setHeader('Access-Control-Allow-Headers','*');
//设置响应体
response.send("HELLO AJAX POST");
})*/
//可以接收任意类型的数据
app.all('/server',(request,response)=>{
//设置响应头 (此处设置允许跨域)
response.setHeader('Access-Control-Allow-Origin','*');
//响应头
response.setHeader('Access-Control-Allow-Headers','*');
//设置响应体
response.send("HELLO AJAX POST");
})
//监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中...");
})
七、 服务端响应JSON数据
JSON.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX GET请求</title>
<style>
#result{
width:200px;
height:100px;
border: aqua solid 1px;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
const result=document.getElementById("result");
//绑定事件
window.onkeydown=function(){
//1.创建对象
const xhr=new XMLHttpRequest();
//设置响应体数据的类型
xhr.responseType='json';
//2.初始化 设置请求方法和url
xhr.open('Get','http://127.0.0.1:8000/json-server');
//3.发送
xhr.send();
//4.事件绑定 处理服务端返回的结果
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300){
/*
//1.手动对数据转化
//JSON.parse(json字符串):把json数据反序列化为一个js对象。
let data=JSON.parse(xhr.response);
console.log(data);
result.innerHTML=data.name;*/
//2.自动转化(即设置响应体数据的类型)
console.log(xhr.response);
result.innerHTML=xhr.response.name;
}
}
}
}
</script>
</body>
</html>
服务器端:
//引入express
const express=require('express');
//创建应用对象
const app=express();
//创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
//可以接收任意类型的数据
app.all('/json-server',(request,response)=>{
//设置响应头 (此处设置允许跨域)
response.setHeader('Access-Control-Allow-Origin','*');
//响应头
response.setHeader('Access-Control-Allow-Headers','*');
//设置响应体(响应体一定是字符串)
const data={name:'zhangSan'};
//JSON.stringify( {} , [ ] , ""),把数据序列化为json字符串
let str=JSON.stringify(data);
response.send(str);
})
//监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中...");
})
八、IE缓存问题解决
九、请求超时与网络异常处理
发送端;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>请求超时与网络异常处理</title>
<style>
#result{
width:200px;
height:200px;
border:solid 1px aqua;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
const btn=document.getElementsByTagName('button')[0];
const result=document.querySelector('#result');
btn.addEventListener('click',function(){
const xhr=new XMLHttpRequest();
//超时设置
xhr.timeout=2000;
//超时回调
xhr.ontimeout=function(){
alert("网络异常,请稍后尝试");
}
// 网络异常回调
xhr.onerror=function(){
alert("你的网络似乎出了一些问题");
}
xhr.open("GET",'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<300){
result.innerHTML=xhr.response;
}
}
}
})
</script>
</body>
</html>
服务器端:
//引入express
const express=require('express');
//创建应用对象
const app=express();
//创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/delay',(request,response)=>{
//设置响应头 (此处设置允许跨域)
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
setTimeout(()=>{
response.send("请求延迟");
},3000)
})
//监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中...");
})
十、点击发送与取消及请求重复发送问题
发送端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>取消请求</title>
</head>
<body>
<button>请求发送</button>
<button>点击取消</button>
</body>
<script>
const btns=document.querySelectorAll('button');
//注意,这里不能使用const定义,因为它修饰的变量值不能变更
let x=null;
//标识变量
let isSending=false;//是否正在发送AJAX请求
btns[0].onclick=function(){
//判断标识变量
//如果正在发送,则取消该请求,创建一个新的请求
if(isSending)x.abort();
x=new XMLHttpRequest();
isSending=true;
x.open("GET",'http://127.0.0.1:8000/delay');
x.send();
x.onreadystatechange=function(){
if(x.readyState===4){
isSending=false;
}
}
}
//点击取消
btns[1].onclick=function(){
//立即终止当前进程,产生异常程序终止
x.abort();
}
</script>
</html>
服务器代码参照九