AJAX含义
Asynchronous JavaScript And XML:异步JavaScript和XML
它的实例化对象是:
let xhr = new XMLHttpRequest();
下面我会详细介绍ajax的用法~~原生和jquery
包括原生get\post JQuery get\post\通用型 axios get\post\通用型 以及fetch get\post
优点
- 在前端页面不刷新的情况下向服务器端发送http请求
- 可以根据点击事件更新页面部分内容
- 根据用户特定行为来向服务端发请求
缺点
- 它不能被 window.history对象 记录浏览历史,不能回退。
- 因为AJAX遵循同源策略,所以存在跨域问题。
- 搜索引擎优化(SEO)并不友好,不利于爬虫抓取数据(ctrl+f 无法获取网页文字)。
特点(使用场景)
- 可以在前端页面不刷新的情况下向服务器端发送http请求从而得到http响应。
常用请求方式
- get:根据get传参查询数据
- post:插入数据
post的三种请求类型:
(1)Content-Type: application/json => {id:1}
(2)Content-Type: multipart/form-data => let data = new FormData(); data.append(‘id’,‘1’);
(3)Content-Type: application/x-www-form-urlencoded => JSON.stringify({id:1}); - pull:修改数据
- delete:删除数据
优势
~~可以无刷新的向服务器获取数据。
页面数据很多的情况下用户并不需要看到所有的数据,这个时候可以让用户先看到一个概览数据,然后再点击需要浏览的数据。
比如:
-
报表:无需向用户展示数据库所有行的数据 而是分页展示部分数据然后用户点击下一页 或 按照特定列检索进而向服务器请求部分数据。
-
统计分析:数据在宏观上的情况概览,然后点击指定的统计分析数据查看与之相关的详细数据。
-
瀑布流:手机端或电脑端展示商品或其他数据时不一定要把所有商品全部展示,而是展示一小部分,等用户浏览完毕在加载另外一小部分(我们可以监听滚轴事件)。
-
导航:当数据量过大时,可以通过一级导航、二级导航甚至更多先对数据进行统计、分类整理,然后点击某个导航 进行数据的分页展示。
HTTP协议
含义:超文本传输协议Hyper Text Transfer Protocol,运行在TCP之上
它详细规定了浏览器和万维网之间互相通信的规则,大家都按照同一种规则办事。
常见的参数
请求报文
- 请求行
get /user?name=张三 HTTP/1.1 :
get:请求类型
/user?name=张三 :请求路径以及查询字符串
HTTP/1.1:使用的协议以及版本号 - 请求头
Content-type: application/x-www-form-urlencoded - 空行
固定写法 必须有 - 请求体
get请求 请求体为空 post请求 请求体不为空
username=admin&password=admin
响应报文
- 响应行
HTTP/1.1 200 OK
HTTP/1.1:协议以及版本号
200:响应状态码
OK是对响应状态码的描述 - 响应头
Content-Type: text/html; charset=utf-8
content-length: 2048 Content-encoding: gzip - 空行
固定写法 必须有
4.响应体
是html代码 其中包含css js等
响应状态码
100~200之间 表示服务器端接收了部分请求,需等待
200~300之间 表示成功
300~400之间 表示重定向
400~500之间 表示客户端错误
500~600之间 表示服务器崩溃
同源策略~~浏览器的一种安全策略
概念
网页来自于一个服务器 那么网页向本身所在的服务器发请求 就是同源,否则就是跨域(当前页面url 和请求的url 协议 || 域名 || 端口号不一样)。
违背同源策略就是跨域 – 一台服务器没办法向所有用户提供服务 那么就需要多台服务器等等情况。
代码实现 --亲测有效,别嫌多啊~~哈哈
----------------原生post请求----------------------
客户端
<!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>Document</title>
</head>
<body>
<script>
//创建对象
let xhr = new XMLHttpRequest();
//初始化设置请求方法 和 URL
xhr.open("post", "http://127.0.0.1:3000/user", true);
//设置请求头 为了发送数据的编码正常
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//发送
xhr.send(`uname=张三&upwd=2`);
xhr.onreadystatechange = function () {
// readyState 对应5个值 0 1 2 3 4
if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.status); //状态码
console.log(xhr.statusText); //状态字符串
console.log(xhr.getAllResponseHeaders()); //所有响应头
console.log(xhr.response); //响应体
}
};
</script>
</body>
</html>
服务器端(nodejs)
需要引包 npm i express cors
const express = require("express");
const cors = require("cors");
const app = express(); //创建WEB服务器
app.use(cors()); //正规军解决ajax跨域问题
//监听本地3000端口
app.listen(3000, () => {
console.log("服务已启动 :>> 端口号3000");
});
//通过 express中间件,来解析客户端发来的 url-encoded 格式的数据
app.use(express.urlencoded({ extended: false }));
//监听post请求
app.post("/user", (req, res) => {
console.log("req :>> ", req.body);
res.send(req.body);
});
----------------原生get请求----------------------
客户端
<script>
//创建对象
let xhr = new XMLHttpRequest();
//初始化设置请求方法 和 URL
xhr.open("get", "http://127.0.0.1:3000/user", true);
//设置请求头 为了发送数据的编码正常
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//发送 get请求没有请求体 无需写send的参数
xhr.send();
xhr.onreadystatechange = function () {
// readyState 对应5个值 0 1 2 3 4
if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.status); //状态码
console.log(xhr.statusText); //状态字符串
console.log(xhr.getAllResponseHeaders()); //所有响应头
console.log(xhr.response); //响应体
}
};
</script>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上post请求
//监听get请求
app.get("/user", (req, res) => {
console.log("req :>> ", req.query);
res.send(req.body);
});
----------------JQuery get请求----------------------
客户端
<script>
//首先引入jquery.min.js文件 回调函数也可用 function(data){} 的形式
$.get("http://127.0.0.1:3000/user",{ a: 1, b: 2 },(data) => {
console.log("data :>> ", data);
},"json"); //第四个参数设置响应体类型 不加json data则是json字符串
</script>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上原生post请求
//监听get请求
app.get("/user", (req, res) => {
console.log("req :>> ", req.query);
res.send(req.query);
});
----------------JQuery post请求----------------------
客户端
<script>
//首先引入jquery.min.js文件 回调函数也可用 function(data){} 的形式
$.post("http://127.0.0.1:3000/user",{ a: 1, b: 2 },(data) => {
console.log("data :>> ", data);
},"json"); //第四个参数设置响应体类型 不加json data则是json字符串
</script>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上原生post请求
//监听post请求
app.post("/user", (req, res) => {
console.log("req :>> ", req.body);
res.send(req.body);
});
*---------JQuery 通用型请求 get post 请求只需把type: “get”,//请求类型更改即可---------
客户端
<script>
$.ajax({
url: "http://127.0.0.1:3000/user",//请求网址
data: { a: 1, b: 2 },//发送给服务器端的数据
type: "get",//请求类型 get post ...
dataType: "json",//设置返回的数据格式为json格式
async: true, // false 为同步请求 锁住浏览器其他代码等待ajax完成后执行
cache: false, //设置false 不会从浏览器缓存中加载请求信息
//成功回调
success: (data) => {
console.log("data :>> ", data);
},
//超时时间
timeout: 2000,
//失败回调
error: () => {
alert("请求失败");
},
//自定义头信息
headers: {
c: 1,
d: 2,
},
});
</script>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上原生post请求
//监听get请求
app.get("/user", (req, res) => {
console.log("req :>> ", req.query);
res.send(req.query);
});
----------------axios get请求 (ajax工具库、vue\react 推荐的工具包) ----------------------
***https://www.bootcdn.cn/ ** ~~ 搜索 axios 引入axios文件
引入script文件 可以添加一个属性避免报一些无用的异常 crossorigin=“anonymous”
客户端
<script>
axios.defaults.baseURL = "http://127.0.0.1:3000";
//get请求
axios.get("/user", {
params: {id: 1,},
//请求头信息
headers: {h: 1,},
}).then((data) => {
console.log("data :>> ", data);
});
//更多axios参数以及用法百度即可
</script>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上原生post请求
//监听get请求
app.get("/user", (req, res) => {
console.log("req :>> ", req.query);
res.send(req.query);
});
----------------axios post请求 ----------------------
***https://www.bootcdn.cn/ ** ~~ 搜索 axios 引入axios文件
引入script文件 可以添加一个属性避免报一些无用的异常 crossorigin=“anonymous”
注:post请求的第二个参数是请求发送的数据部分
客户端
<!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" />
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/qs/6.10.3/qs.min.js"></script>
<title>Document</title>
</head>
<body>
<script>
axios.defaults.baseURL = "http://127.0.0.1:3000";
let data = { id: 1 };
let strData = Qs.stringify(data);
//get请求
axios.post("/user", strData, {
params: {
name: "张三",
},
//请求头信息
headers: {
h: 1,
},
}).then((data) => {
console.log("data :>> ", data);
});
//更多axios用法百度即可
</script>
</body>
</html>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上原生post请求
//监听post请求
app.post("/user", (req, res) => {
console.log("req :>> ", req.body);
res.send(req.body);
});
----------------fetch函数发送get请求(全局函数) ----------------------
客户端
<script>
fetch("http://127.0.0.1:3000/user?id=1&name=2", {
method: "get",
headers: {
name: "aaa",
},
}).then((res) => {
//return res.text();
return res.json();
}).then((res) => {
console.log("res :>> ", res);
});
</script>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上原生post请求
//监听get请求
app.get("/user", (req, res) => {
console.log("req :>> ", req.query);
res.send(req.query);
});
----------------fetch函数发送post请求(全局函数) ----------------------
客户端
<script>
fetch("http://127.0.0.1:3000/user", {
//请求方法
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "id=1&name=2",
}).then((res) => {
//return res.text();
return res.json();
}).then((res) => {
console.log("res :>> ", res);
});
</script>
服务器端(nodejs)
需要引包 npm i express cors 相同代码同上原生post请求
//监听post请求
app.post("/user", (req, res) => {
console.log("req :>> ", req.body);
res.send(req.body);
});
使用AJAX时遇到的常见问题
- 解决IE缓存问题。
//加一个时间戳 让每次请求都不一样
xhr.open("get", "http://127.0.0.1:3000/login?time='+Date.now());
- 请求超时(自动监听)。
//创建对象
let xhr = new XMLHttpRequest();
//设置2s后超时
xhr.timeout = 2000;
//设置超时回调
xhr.ontimeout = function(){
alert("请求超时");
}
- 网络异常。
//创建对象
let xhr = new XMLHttpRequest();
//网络异常回调
xhr.onerror = function(){
alert("网络异常");
}
- 手动取消请求。
//创建对象
let xhr = new XMLHttpRequest();
//手动取消请求 可以把这行代码放到监听事件里
xhr.abort();
- 规避请求重复发送 (用户疯狂点击!!!)。
//点击按钮看之前是否存在这个请求 如果有就把之前的相同请求取消掉
let isAjaxSending = false;//表示是否正在发送AJAX请求
getUserInfo.onclick = function () {
if(isAjaxSending) xhr.abort();//如果正在发送 取消该请求 创建一个新的请求
isAjaxSending = true; //true 代表当前正在发送请求 只有响应成功了才是false(没有当前客户端发送请求)
let xhr = new XMLHttpRequest();
xhr.open("get",`http://127.0.0.1:3000/user?uid=1`,true );
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
isAjaxSending = false;
}
};
};
- **解决跨域问题。
6.1 CORS
CORS(跨域资源共享)支持get post 新增了http首部字段
前端不需要做任何操作 完全在服务器处理跨域问题
原生写法
const app = express();
app.post("/login", (req, res) => {
//设置允许跨域
res.setHeader("Access-Contro1-Allow-Origin", "*");//*号代表接收所有网页的请求 也可以写指定的url 接收指定网页请求
res.setHeader("Access-Contro1-Allow-Headers", "*");//添加自定义请求头信息
res.setHeader("Access-Contro1-Allow-Method", "*");//添加请求类型 *号代表所有请求类型
});
引入CORS模块 npm i cors
const app = express();
引入cors包
const cors = require("cors");
//app.use(cors());//表示接收所有跨域请求
origin:['http://localhost:8848','http://127.0.0.1:8848',
'http://localhost:5500','http://127.0.0.1:5500'], //指定接收的地址
methods:['get','post','delete','put'], //指定接收的请求类型
alloweHeaders:['Content-Type','Authorization'] //指定header
6.2 JSONP
借助于具有跨域属性的标签实现跨域 ~~
nodejs 返回标准的js代码 或者函数调用
app.get('/user/getUserInfo',(req,res)=>{
let data = {'1':123};
res.send(`alert('123')`);//返回标准的js代码
res.end(` serverData(${data})`);//返回一个函数调用
});
~~如果想看视频学习的话 推荐 b站:【尚硅谷】3小时Ajax入门到精通
https://www.bilibili.com/video/BV1WC4y1b78y?spm_id_from=333.337.search-card.all.click