AJAX 的开发笔记
HTTP
HTTP(hypertext transport protocol)协议『超文本传输协议』,协议详细规定了浏览器和万维网服务器之间互相通信的规则。
约定, 规则
请求报文
重点是格式与参数
行 POST /s?ie=utf-8 HTTP/1.1
头 Host: atguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded
User-Agent: chrome 83
空行
体 username=admin&password=admin
响应报文
行 HTTP/1.1 200 OK
头 Content-Type: text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip
空行
体 <html>
<head>
</head>
<body>
<h1>尚硅谷</h1>
</body>
</html>
响应的状态码
- 404
- 403
- 401
- 500
- 200
原生AJAX
GET请求的使用
// 获取button元素对象
const btn = document.querySelector('button'); // 通过该方法可以直接通过标签选择器来获取对象
const box = document.querySelector('.box');
// 绑定事件
btn.onclick = function(){
// 分4步
// 1,创建对象
const xhr = new XMLHttpRequest();
// 2,初始化,设置请求方法和url 即要请求的url地址
xhr.open('GET','http://127.0.0.1:8000/server');
// 3,发送
xhr.send();
// 4,事件绑定 处理服务器返回的结果
// on when 当...时候 触发
// readystate 是 xhr 对象中的属性, 表示请求的状态 0 1 2 3 4
// change 改变
xhr.onreadystatechange = function(){
// 判断 当服务器返回了所有的结果时
if(xhr.readyState === 4){
// 判断状态码 200 404 403 401 500
// 只要是200到300以内的状态码 都是表示成功
if(xhr.status >= 200 && xhr.status < 300){
// 处理结果 处理响应的 行 头 空行 体
//响应
// console.log(xhr.status); // 状态码
// console.log(xhr.statusText); // 状态字符串
// console.log(xhr.getAllResponseHeaders()); // 所有响应头
// console.log(xhr.response); // 响应体
// 将获取到响应体 显示在box div中
box.innerHTML = xhr.response;
}
}
}
}
POST请求的使用
// 获取元素对象
const box = document.querySelector('.box');
// 绑定事件 当鼠标移到该div对象上时,触发该事件
box.addEventListener('mousemove',function(){
// console.log('text');
// 4步
//1,创建对象
const xhr = new XMLHttpRequest();
//2,初始化 设置类型与URL
xhr.open('POST','http://127.0.0.1:8000/server');
// 设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
//3,发送
xhr.send('name = "小爱"……age=18'); // send的方法可以发送请求参数 数据要用引号包起来,因为只能是字符串
//4,事件绑定
xhr.onreadystatechange = function(){
// 该事件只会在请求请求发送后结束后就会触发
// 判断发送结束,返回的状态
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
// 处理服务端返回的结果
box.innerHTML = xhr.response;
}
}
}
})
JSON响应的处理
游览器端
const box = document.querySelector('.box');
// 绑定键盘的按下事件,这个可以是任意键
window.onkeydown = function(){
// 发送ajax请求 4步走
const xhr = new XMLHttpRequest();
// 设置响应体数据的类型
xhr.responseType = 'json'; // 如果是手动转换就不要该行代码
// 初始化,设置发送的请求类型和要请求的url地址
xhr.open('GET','http://127.0.0.1:8000/json-server')
// 发送请求参数
xhr.send();
// 事件绑定 一旦发送结束,就触发该事件
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){ // 该判断表示已经得到返回的请求的结果了
if(xhr.status >= 200 && xhr.status <300){
// box.innerHTML = xhr.response;
// 手动对数据转换
// 通过JSON对象的parse()方法将一个json字符串转换为一个对象
// let obj = JSON.parse(xhr.response);
// box.innerHTML = obj.name;
// console.log(obj);
//自动转换
console.log(xhr.response);
box.innerHTML = xhr.response.name;
}
}
}
}
服务器端
//1,第一步,引入express包
const express = require('express');
//2,第二步创建应用对象
const app = express();
//3,创建路由规则
// request 是对请求对象报文的封装 即请求对象
// response 是对响应报文的封装,即响应对象
// 配置路由
// 接收get类型的请求
app.get('/server', (request, response) => {
// 设置响应头,即请求头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('HELLO AJAX');
})
// 接收post类型的请求
app.post('/server', (request, response) => {
// 设置响应头,即请求头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('HELLO AJAX');
})
// 接收任意类型的请求
app.all('/json-server', (request, response) => {
// 设置响应头,即请求头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应一个对象给他
const data = {
name:'atguigu'
}
// t通过JSON对象的stringify()方法将一个对象转换为json类型的数据
let str = JSON.stringify(data);
// 设置回复该请求的响应体
response.send(str);
})
// 4,监听端口启动服务
app.listen(8000, () => {
console.log('服务已经启动 http://127.0.0.1:8000/server');
});
IE缓存问题
浏览器端
// 2,设置请求的类型和要请求的url地址 发送一个请求参数,
//将当前时间戳作为参数发送过去,这样浏览器就不会使用本地的缓存了
xhr.open('GET','http://127.0.0.1:8000/ie?t='+Date.now());
服务器端
// 4,针对IE缓存问题
app.get('/ie', (request, response) => {
// 设置响应头,即请求头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('HELLO IE');
})
发送请求超时与网络异常问题
浏览器端
// 绑定事件
btn.addEventListener('click',function(){
// 4,步骤
// 1,新建一个ajax的对象
const xhr = new XMLHttpRequest();
// 设置延时2s
xhr.timeout = 2000;
// 延时回调 即xhr对象发送请求时,延时的时候会调用的函数
xhr.ontimeout = function(){
alert('网络异常,请稍后重试!!!');
}
// 网络异常回调 发送请求时,出现网络出现异常时,会自动调用的回调函数
xhr.onerror = function(){
alert('你的网络似乎出现了一些问题!')
}
// 2,设置请求的类型和要请求的url地址
xhr.open('GET','http://127.0.0.1:8000/delay')
})
服务器端
// 5,延时响应
app.get('/delay', (request, response) => {
// 设置响应头,即请求头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
// 定义一个定时器函数
setTimeout(() => {
// 设置响应体
response.send('HELLO err');
}, 3000);
})
取消ajax请求
浏览器端
btns[1].onclick = function(){
// 通过ajax对象的abort()方法即可取消点这个发送请求
x.abort();
}
重复请求问题
浏览器端
// 获取元素对象
const btns = document.querySelectorAll('button');
// 定义一个变量用来存放ajax对象
let x = null;
// 定义一个标识符变量。用来记录发送的状态
let isSending = false; // 是否正在发送ajax请求
// 绑定事件
btns[0].addEventListener('click',function(){
// 判断发送标识的状态
if(isSending) {
x.abort(); //如果正在发送,则取消该请求,然后后面创建一个新的ajax请求
}
x = new XMLHttpRequest();
// 修改发送请求的状态
isSending = true; // 表示正在发送请求
x.open('GET','http://127.0.0.1:8000/delay');
x.send();
if(x.readyState === 4){
// 修改标识符
isSending = false; // 表示没有在发送请求,因为已经发送结果
}
})
fetch() 函数发送ajax请求
浏览器端
//获取对象
const btn = document.querySelector('button');
btn.onclick = function(){
// 通过fetch函数发送ajax请求
fetch('http://127.0.0.1:8000/fetch',{
// 请求方法
method:'POST',
// 请求头
headers:{
name:'wotule '
},
// 请求体
body:'username=admin&password=admin'
}).then(response =>{
// fetch 函数的返回值也是一个promise异步对象
// return response.text();
// 如果服务器返回的是json字符串对象,即使用下面方法
return response.json();
}).then(response =>{
console.log(response);
})
}
服务器端
// 6,axios服务响应
app.all('/fetch', (request, response) => {
// 设置响应头,即请求头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
let obj = {
name:'xiaoai',
age :18
}
response.send(JSON.stringify(obj));
})
跨域问题,解决一 jsonp方法,使用script标签
浏览器端
<div id="result"></div>
<script>
//处理数据
function handle(data) {
//获取 result 元素
const result = document.getElementById('result');
result.innerHTML = data.name;
}
</script>
<!-- <script src="http://127.0.0.1:5500/%E8%AF%BE%E5%A0%82/%E4%BB%A3%E7%A0%81/7-%E8%B7%A8%E5%9F%9F/2-JSONP/js/app.js"></script> -->
<script src="http://127.0.0.1:8000/jsonp-server"></script>
服务器端
//jsonp服务
app.all('/jsonp-server',(request, response) => {
// response.send('console.log("hello jsonp")');
const data = {
name: '尚硅谷atguigu'
};
//将数据转化为字符串
let str = JSON.stringify(data);
//返回结果 返回的结果要是一个js代码的字符串
response.end(`handle(${str})`);
});
跨域问题,解决二 ,使用官方的方法CORS
服务器端
app.all('/cors-server', (request, response)=>{
//设置响应头,加上下面的3行代码即可实现跨域
response.setHeader("Access-Control-Allow-Origin", "*"); // 表示允许任何url地址请求
response.setHeader("Access-Control-Allow-Headers", '*');// 表示允许任何类型的请求头
response.setHeader("Access-Control-Allow-Method", '*'); // 表示允许任何类型的请求方法
// response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500"); // 该行代码表示指定只能该url地址访问该服务器
response.send('hello CORS');
});