目录
1. AJAX的特点
1.1 AJAX的优点
- 可以无需刷新页面而与服务器端进行通信。
- 允许你根据用户事件来更新部分页面内容。
1.2 AJAX的缺点
- 没有浏览历史,不能回退。
- 存在跨域问题。
- 搜索引擎优化不友好,爬虫爬不到。
2. HTTP
2.1 请求报文
请求行:请求类型(GET、POST...) URL路径 HTTP协议版本
请求头:Host: atguigu.com
Cookie: name=guigu
Content-Type: application/x-www-form-urlencoded
User-Agent: chrome 83
空行
请求体:GET为空,POST可以不为空
2.2 响应报文
响应行:HTTP协议版本 状态码(200...) 状态字符串(OK)
响应头:Content-Type: text/html
Content-length: 2048
Content-encoding: gzip
空行
响应体:html
3. Express服务端框架
1. 安装express
npm i express
2. 使用
// 引入express
const express = require('express');
// 创建应用对象
const app = express();
// 创建路由规则
// request 是对请求报文的封装,response是对响应报文的封装
app.get('/server',(request,response)=>{
// 设置响应头允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 设置响应体
response.send('hello');
});
// 监听端口启动服务
app.listen(8000, ()=>{
console.log('服务已经启动,8000端口监听中...');
});
4. AJAX请求操作
4.1 发送请求
// 创建对象
const xhr = new XMLHttpRequest();
// 初始化设置请求方法和url
xhr.open('GET','http://127.0.0.1:8000/server');
// 发送
xhr.send();
// 处理服务端返回的结果
xhr.onreadystatechange = function(){
//判断服务端返回了所有结果
if(xhr.readyState === 4){
//判断响应状态码成功
if(xhr.status >= 200 && xhr.status < 300){
//处理结果
console.log(xhr.status);//状态码
console.log(xhr.statusText);//状态字符串
console.log(xhr.getAllResponseHeaders());//所有响应头
console.log(xhr.response);//响应体
}
}
}
4.2 设置请求参数
1. GET请求
xhr.open('GET','http://127.0.0.1:8000/server?a=100&b=200');
2. POST请求
// xhr.send('a=100&b=200');
// xhr.send('a:100&b:200');
xhr.send('100');
4.3 设置请求头信息
1. 预定义
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
2. 自定义
xhr.setRequestHeader('name','atguigu');
// 注意:1.服务端需设置响应头response.setHeader('Access-Control-Allow-Headers','*')。
// 2.此时还会发送OPTIONS请求校验头信息是否可用,服务端改为app.all('/server',(request,response)=>{}),表示可以接收任意类型的请求。
4.4 服务端响应JSON数据
1. 服务端
const data = {
name: 'atguigu',
};
// 对对象进行字符串转换
let str = JSON.stringify(data);
response.send(str);
2. 前端
// 手动对数据转化,字符串转对象
let data = JSON.parse(xhr.response);
//自动转化,设置响应体数据的类型
xhr.responseType = 'json';
4.5 IE缓存问题
IE浏览器对Ajax请求结果做缓存,再次请求时拿到的是缓存中数据,而不是服务器最新数据,影响实效性。
xhr.open('GET','http://127.0.0.1:8000/server?t='+Date.now()); // Date.now()获取当前时间戳,每次请求url不一样。
4.6 请求超时与网络异常处理
// 超时设置2s,超时取消请求
xhr.timeout = 2000
// 超时回调
xhr.ontimeout = function(){
alert("网络异常,请稍后重试!");
}
// 网络异常回调
xhr.onerror = function(){
alert("");
}
4.7 取消请求
xhr.abort();
4.8 请求重复发送问题
定义一个标识变量isSending判断是否正在发送AJAX请求。
if(isSending) xhr.abort(); // 发送请求时先判断isSending,如果正在发送,则取消该请求创建一个新的请求
xhr = new XMLHttpRequest();
isSending = true; // 发送请求前修改isSending
xhr.open(...);
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
isSending = false; // 服务端返回了所有结果请求完成后修改isSending
}
}
5. jQuery发送AJAX请求
// 引入
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
5.1 GET/POST请求
$.get('http://127.0.0.1:8000/jquery-server',{a:100,b:200},function(data){
console.log(data);
},'json')
$.post('http://127.0.0.1:8000/jquery-server',{a:100,b:200},function(data){
console.log(data);
})
5.2 通用方法请求
$.ajax({
url:'http://127.0.0.1:8000/jquery-server',
data:{a:100,b:200},
type:'GET',
// 响应体结果
dataType:'json',
// 成功的回调
success:function(data){
console.log(data);
},
// 超时时间
timeout:2000,
// 失败的回调
error:function(){},
// 头信息
Headers:{}
});
6. Axios发送AJAX请求
// 配置baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
6.1 GET请求
axios.get('/axios-server',{
// url参数
params:{
id:100,
},
// 请求头信息
headers:{},
}).then(value=>{
console.log(value);
});
6.2 POST请求
axios.post('/axios-server',{username:'admin',},{
// url参数
params:{
id:100,
},
// 请求头信息
headers:{},
});
6.3 Axios函数发送请求
axios({
//请求方法
method:'',
url:'/axios-server',
// url参数
params:{
id:100,
},
headers:{},
// 请求体参数
data:{
username:'admin',
password:'',
}
}).then(response=>{
console.log(response);
});
7. fetch函数发送AJAX请求
fetch('http://127.0.0.1:8000/fetch-server?vip=10',{
//请求方法
method:'POST',
headers:{},
// 请求体参数
body:'username=admin&password=admin'
}).then(response=>{
// return response.text();
return response.json();
}).then(response=>{
console.log(response);
});
8. 跨域
同源:协议、域名、端口号必须完全相同。
违背同源策略就是跨域。
8.1 JSONP解决跨域(非官方)
在网页有一些标签天生具有跨域能力,比如:img link iframe script。JSONP就是利用script标签的跨域能力来发送请求的。
<script src=”http://127.0.0.1:8000/jsonp-server”></script>服务端返回js代码。
8.1.1 原生jsonp实践
// 创建script标签
const script = document.createElement('script');
// 设置标签的src属性
script.src = 'http://127.0.0.1:8000/jsonp-server';
// 将script插入到文档中
document.body.appendChild(script);
8.1.2 jQuery发送jsonp请求
$.getJSON('http://127.0.0.1:8000/jsonp-server?callback=?',function(data){
console.log(data);
})
// 服务端
app.all('/jsonp-server',(request,response)=>{
const data = {
name:'',
city:['北京',]
};
let str = JSON.stringify(data);
let cb = request.query.callback;
response.end(`${cb}(${str})`);
})
8.2 设置CORS响应头实现跨域(官方)
特点:不需要在客户端做任何特殊的操作,完全在服务器中进行处理。
原理:设置一个响应头来告诉浏览器,该请求允许跨域。
// 服务端设置响应头
// response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');