前言
在二次开发人脸识别来进行注册登录时,卡在了前端网页上传图片到后端这一步,莫得办法,只得来学习前端的jQuery和AJAX看看能不能解决问题
原生AJAX
目录
![](https://img-blog.csdnimg.cn/img_convert/cbd31aa38370288e8091558a08004e95.png)
1.1 AJAX简介
![](https://img-blog.csdnimg.cn/img_convert/fa5b000afcb73e23e67fa61abfb01907.png)
1.2 XML简介
XML全称:Extensible Markup Language,即可扩展标记语言
XML被设计用来传输和存储数据
XML和HTML类似,不同的是HTML中都是预定义标签(预先定义好的标签),而XML中没有预定义标签,全都是自定义标签,用来表示一些数据
之前服务器返回XML格式字符串,而现在则改为JSON格式字符串
示例:
学生数据:name = "孙悟空"; age = 18; gender = "男";
用XML格式表示
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
用JSON格式表示
{"name":"孙悟空","age":18,"gender":"男"}
简言之,在数据交换这一块儿,XML已被JSON取代
1.3 AJAX的特点
1.3.1 AJAX的优点
可以无刷新页面与服务端进行通信
允许根据用户事件来更新部分页面内容
1.3.2 AJAX的缺点
没有浏览历史,不能回退
存在跨域问题(同源)
SEO (Search Engine Optimization)不友好,也就是搜索引擎爬取不到网站相关内容信息,无法有效提高网站访问量(爬虫爬取不到相关内容)
1.4 HTTP协议请求报文与响应报文文本结构
HTTP (hypertext transfer protocol)协议【超文本传输协议】,协议详细规定了浏览器和万维网服务器之间互相通信的规则
1.4.1 请求报文
重点看其格式与参数
行 由三部分组成,分别是:请求方法字段+URL字段+HTTP协议版本 如:POST /s?wd=谷粒学院 HTTP/1.1
头 由键值对组成,每行一对,键和值之间使用冒号分隔
Host: atguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded
User-Agent: chrome 83
空行
体 可选部分,比如GET请求就没有请求体
username=admin&password=admin
GET请求被指定用于客户端从服务器获取资源,POST请求被指定于客户端向服务器提交资源
1.4.2 响应报文
行 由三部分组成,分别是:协议版本 状态码 状态码描述 如: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>
1.5 Chrome网络控制台查看通信报文
请求报文查看
![](https://img-blog.csdnimg.cn/img_convert/26c0f975b7e74e29bb6a3c54d5d3a9f8.png)
![](https://img-blog.csdnimg.cn/img_convert/9b164bd8ee40e973657bc84d695065d7.png)
Preview也就是响应预览,即对响应资源进行了格式化处理
Response也就是原始响应内容,即未进行格式处理的内容
![](https://img-blog.csdnimg.cn/img_convert/f3d878fcefdb8f3f0d92a14d8f110170.png)
响应报文查看
![](https://img-blog.csdnimg.cn/img_convert/fb1c52e670bd266a235c1df369286400.png)
![](https://img-blog.csdnimg.cn/img_convert/ba46c03f081b16bc1fcdbce8116b316f.png)
1.6 Node.js安装与介绍
AJAX应用当中需要一个服务端,去Node.js官网下载Node.js
![](https://img-blog.csdnimg.cn/img_convert/07c7b35116703b25fa0777da4e423e92.png)
忘记了啥时候安装的,检查是否安装完成
![](https://img-blog.csdnimg.cn/img_convert/5964108f6cdb6f5ceb5faef160ceead2.png)
1.7 Express框架介绍与基本使用
来到Express官网,可以了解Express框架的简介以及快速入门
![](https://img-blog.csdnimg.cn/img_convert/35c6245984d62aa025fcf8f4cc490448.png)
NPM是Node.js标准的软件包管理器,是随同Node.js一起安装的包管理工具,能解决Node.js代码部署上的很多问题,常见的使用场景如下:
允许用户从NPM服务器下载别人编写的第三方包到本地使用
允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用
允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用
新版Node.js已经集成了NPM,所以要想使用NPM就得安装Node.js
Express快速入门
![](https://img-blog.csdnimg.cn/img_convert/2599c96c21af9954074f39982e1569f5.png)
![](https://img-blog.csdnimg.cn/img_convert/2f578a746fa625ba1f22849e3b6269cd.png)
![](https://img-blog.csdnimg.cn/img_convert/b74f5b4d549e16ed68ae0b5584cd1e8c.png)
![](https://img-blog.csdnimg.cn/img_convert/9b42c2962e6c8b98ec8bc6a35a74b54c.png)
![](https://img-blog.csdnimg.cn/img_convert/4f4e549a270af61145335e906c164799.png)
1.8 GET请求
点击按钮发送请求,将服务端返回的响应体结果在div中呈现,页面不刷新
先释放端口,防止端口被占用(所谓端口可以理解为服务窗口)
![](https://img-blog.csdnimg.cn/img_convert/c6f9e04153c36805da4297160522c2ff.png)
查看启动效果
![](https://img-blog.csdnimg.cn/img_convert/c5a36ab20295bfef0d28ecd64be3005b.png)
测试响应效果
![](https://img-blog.csdnimg.cn/img_convert/37d3f8d9d71453a8f08ea996b44fd31e.png)
![](https://img-blog.csdnimg.cn/img_convert/ba48f8402dfb558cfa1b3f2f91e24c6a.png)
完成案例
![](https://img-blog.csdnimg.cn/img_convert/7a70d490b9fe97fd7deaa3519d171c6c.png)
<!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: solid 1px #90b;
}
</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. 创建对象
const xhr = new XMLHttpRequest();
// 2. 初始化 设置请求方法和 url
xhr.open('GET', 'http://localhost: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 ...
// 2xx 成功
if (xhr.status >= 200 && xhr.status < 300) {
// 处理结果 行 头 空行 体
// 响应报文
/* console.log(xhr.status); // 状态码
console.log(xhr.statusText); // 状态字符串
console.log(xhr.getAllResponseHeaders); // 所有响应头
console.log(xhr.response); // 响应体
*/
// 设置 result 的文本
result.innerHTML = xhr.response;
}else{
}
}
}
}
</script>
</body>
</html>
// 1. 引入express
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response)=>{
// 设置响应体, 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('HELLO AJAX');
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
设置请求参数
![](https://img-blog.csdnimg.cn/img_convert/8318a5f22afb63eafff3cb04db829dcf.png)
![](https://img-blog.csdnimg.cn/img_convert/b2ab2bf230af161039524b2e0a560a36.png)
1.9 POST请求
1.9.1 发送请求
效果
![](https://img-blog.csdnimg.cn/img_convert/cba42389f3ef781b09a1c369d626a343.png)
<!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://localhost:8000/server');
// 3. 发送
xhr.send();
// 4. 事件绑定
xhr.onreadystatechange = function(){
// 判断
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
}
})
</script>
</body>
</html>
// 1. 引入express
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// 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.send('HELLO AJAX POST');
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
1.9.2 设置请求体
![](https://img-blog.csdnimg.cn/img_convert/9157c7e20564ee10961524f3ec2aa2f4.png)
![](https://img-blog.csdnimg.cn/img_convert/00129176d7de200a6f5ac4e2226a1de8.png)
1.9.3 设置请求头
设置预定义请求头
![](https://img-blog.csdnimg.cn/img_convert/d086f5a1988f44455f55d0fb4ead42a3.png)
![](https://img-blog.csdnimg.cn/img_convert/e1441baa6de355f70ab37b319e83433b.png)
设置自定义请求头
![](https://img-blog.csdnimg.cn/img_convert/e7ae836a6edba7195567efe7a3f1e1b4.png)
![](https://img-blog.csdnimg.cn/img_convert/f871917b953f0c0bf5ac64636fdcdb52.png)
2.0 服务端响应JSON数据
效果
![](https://img-blog.csdnimg.cn/img_convert/c91ba7b634c605da7e0f3ca5c3550cc0.png)
<!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>JSON响应</title>
<style>
#result {
width: 200px;
height: 100px;
border: solid 1px #89b;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
const result = document.getElementById('result');
// 绑定键盘按下事件
window.onkeydown = function() {
// 发送请求
const xhr = new XMLHttpRequest();
// 设置响应体数据的类型
xhr.responseType = 'json';
// 初始化
xhr.open('GET', 'http://localhost:8000/json-server');
// 发送
xhr.send();
// 事件绑定
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
// result.innerHTML = xhr.response;
// 手动对数据转化
// let data = JSON.parse(xhr.response);
// console.log(data);
// result.innerHTML = data.name;
// 自动转换
console.log(xhr.response);
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
</html>
// 1. 引入express
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response)=>{
// 设置响应体, 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('HELLO AJAX');
})
app.all('/server', (request, response)=>{
// 设置响应体, 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// 设置响应体
response.send('HELLO AJAX POST');
})
app.all('/json-server', (request, response)=>{
// 设置响应体, 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// 响应一个数据
const data = {
name: 'atguigu'
};
// 对对象进行字符串转换
let str = JSON.stringify(data);
// 设置响应体
response.send(str);
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
2.1 nodemon自动重启工具安装与使用
在编写调试node.js项目时,如果修改项目代码,需要频繁手动close,然后重新启动,非常繁琐,现在使用nodemon工具,它能够监听项目文件的变动,当代码被修改后,nodemon会自动帮助重启项目,极大方便了开发和调试
![](https://img-blog.csdnimg.cn/img_convert/28e5668a69888d294926ab1acaaeb824.png)
在终端中,运行如下命令,即可将nodemon安装为全局可用的工具:
npm install -g nodemon
在终端中,运行如下命令,即可查询nodemon是否安装成功
nodemon -v
安装后使用nodemon命令报错
![](https://img-blog.csdnimg.cn/img_convert/ed20ec62bf406cd96c98de50a1c83d52.png)
解决如下
win+r打开运行对话框,然后输入powershell,在弹出的终端窗口输入Start-Process powershell -Verb runAs 命令将权限转到管理员模式
![](https://img-blog.csdnimg.cn/img_convert/025111aaa503f6f636567bf42554e0b3.png)
在管理员身份运行的终端窗口输入 set-ExecutionPolicy RemoteSigned 然后选择Y,最后输入get-ExecutionPolicy 查看是否修改成功
![](https://img-blog.csdnimg.cn/img_convert/8a0e2a5025589d28a0c7eb1048b5a86e.png)
解决后运行效果
![](https://img-blog.csdnimg.cn/img_convert/88d62369797497a1291f360bb80aa54a.png)
2.2 IE缓存问题
IE浏览器会将ajax请求的返回结果进行缓存,如果再遇到相同的ajax请求,就直接在缓存中取结果,这样就得不到最新的服务器响应结果,而Chrome浏览器就不会
解决方案在请求中加个时间戳的请求参数
![](https://img-blog.csdnimg.cn/img_convert/59d0dcaadfe19de1e3c2692d8a6ca38c.png)
<!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>IE缓存问题</title>
<style>
#result{
width: 200px;
height: 100px;
border: 1px solid #258;
}
</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.open("GET",'http://127.0.0.1:8000/ie?t='+Date.now());
// 发送
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
}
})
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 针对IE缓存
app.get('/ie', (request, response)=>{
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('HELLO IE - 3');
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
2.3 请求超时与网络异常处理
效果
![](https://img-blog.csdnimg.cn/img_convert/44514d3bbf3d5352ed12bd866dfef4e1.png)
![](https://img-blog.csdnimg.cn/img_convert/c25ce7aa2b86fee60f006123a187cd94.png)
<!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: 100px;
border: solid 1px #90b;
}
</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();
// 超时设置 2s 设置
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>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 延时响应
app.get('/delay', (request,response)=> {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
setTimeout(() => {
// 设置响应体
response.send('延时响应');
},3000)
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
2.4 取消请求
效果
![](https://img-blog.csdnimg.cn/img_convert/b93cc008452d8b4c46654fb7ad1af14e.gif)
<!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>
<script>
// 获取元素对象
const btns = document.querySelectorAll('button');
let xhr =null;
btns[0].onclick = function(){
xhr = new XMLHttpRequest();
xhr.open("GET",'http://127.0.0.1:8000/delay');
xhr.send();
}
btns[1].onclick = function() {
xhr.abort();
}
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 延时响应
app.get('/delay', (request,response)=> {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
setTimeout(() => {
// 设置响应体
response.send('延时响应');
},3000)
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
2.5 重复请求问题
效果
![](https://img-blog.csdnimg.cn/img_convert/c99891e25ca9a9e657fdfa6946c0831b.png)
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 延时响应
app.get('/delay', (request,response)=> {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
setTimeout(() => {
// 设置响应体
response.send('延时响应');
},3000)
})
// 4. 监听端口启动服务
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>
<script>
// 获取元素对象
const btns = document.querySelectorAll('button');
let xhr =null;
// 标识变量
let isSending = false;
btns[0].onclick = function(){
// 判断标识变量
if (isSending) xhr.abort(); // 如果正在发送,则取消该请求,创建一个新的请求
isSending = true;
xhr = new XMLHttpRequest();
xhr.open("GET",'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
// 修改标识变量
isSending = false;
}
}
}
</script>
</body>
</html>
2.6 jQuery发送AJAX请求
CDN引入jQuery,首先来到BootCDN官网
![](https://img-blog.csdnimg.cn/img_convert/166ad2f96d95dc2c597ba2bda492737c.png)
搜索框中输入jquery,然后点击搜索结果的第一列
![](https://img-blog.csdnimg.cn/img_convert/f4c97336274c1a21f3029b24e474b035.png)
之后复制<script>标签即可
![](https://img-blog.csdnimg.cn/img_convert/08c8c4efa8f63e08556ba556dbba99ea.png)
<!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>jQuery 发送 AJAX 请求</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">jQuery发送AJAX请求</h2>
<button class="btn btn-primary">GET</button>
<button class="btn btn-danger">POST</button>
<button class="btn btn-info">通用型方法ajax</button>
</div>
<script>
$('button').eq(0).click(function(){
$.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data);
},'json')
})
$('button').eq(1).click(function(){
$.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data);
})
})
$('button').eq(2).click(function() {
$.ajax({
// url
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() {
console.log('出错啦!!');
},
// 头部信息
headers: {
c: 300,
d: 400
}
})
})
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// jQuery 服务
app.all('/jquery-server', (request,response)=> {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// response.send('Hello jQuery AJAX');
const data = {name: '尚硅谷'};
response.send(JSON.stringify(data));
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
效果图
![](https://img-blog.csdnimg.cn/img_convert/9bf4fe1c873b8149cf16d75affc12658.jpeg)
![](https://img-blog.csdnimg.cn/img_convert/bb5a48addd417d4689d291aa4b07dcf3.png)
2.7 Axios发送AJAX请求
CDN引入axios,首先来到BootCDN官网,然后搜索框中输入axios,然后点击搜索结果的第一列
![](https://img-blog.csdnimg.cn/img_convert/71dd9c9dca310edcfe6a1f29ca8dacbd.png)
![](https://img-blog.csdnimg.cn/img_convert/205dbf5805cbbab105f1f88e47757f01.png)
<!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>axios 发送 AJAX 请求</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.js"></script>
</head>
<body>
<button>GET</button>
<button>POST</button>
<button>AJAX</button>
<script>
const btns = document.querySelectorAll('button');
// 配置baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[0].onclick = function() {
// GET 请求
axios.get('/axios-server', {
// url 参数
params: {
id: 100,
vip: 7
},
// 请求头信息
headers: {
name: 'atguigu',
age: 20
}
}).then(value => {
console.log(value);
});
}
btns[1].onclick = function() {
axios.post('/axios-server', {
username: 'admin',
password: 'admin'
},{
// url
params: {
id:200,
vip:9
},
// 请求头参数
headers: {
height: 180,
weight: 180
}
})
}
btns[2].onclick = function() {
axios({
// 请求方法
method: 'POST',
// url
url: '/axios-server',
// url参数
params: {
vip: 10,
level: 30
},
// 头信息
headers: {
a: 100,
b: 200
},
// 请求体参数
data: {
username: 'admin',
password: 'admin'
}
}).then(response=>{
console.log(response);
console.log(response.headers);
})
}
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// axios 服务
app.all('/axios-server', (request,response)=> {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// response.send('Hello jQuery AJAX');
const data = {name: '尚硅谷'};
response.send(JSON.stringify(data));
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
效果图
![](https://img-blog.csdnimg.cn/img_convert/2327310734b9d691c7cd4e44c95b00e0.jpeg)
![](https://img-blog.csdnimg.cn/img_convert/950481e31553d59222ea2ce883564181.png)
2.8 使用fetch函数发送AJAX请求
首先看官方对fetch函数的介绍 https://developer.mozilla.org/zh-CN/docs/Web/API/fetch
![](https://img-blog.csdnimg.cn/img_convert/d421a503ee3cc5597b89e9febfa05790.png)
效果图
![](https://img-blog.csdnimg.cn/img_convert/261d0740f6c8cec6a76132e0341e39ed.png)
<!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>fetch 发送 AJAX请求</title>
</head>
<body>
<button>AJAX请求</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
fetch('http://127.0.0.1:8000/fetch-server', {
// 请求方法
method: 'POST',
// 请求头
headers: {
name: 'atguigu'
},
// 请求体
body: 'username=admin&password=admin'
}).then(response => {
return response.json();
}).then(response=> {
console.log(response);
})
}
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// fetch 服务
app.all('/fetch-server', (request,response)=> {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// response.send('Hello jQuery AJAX');
const data = {name: '尚硅谷'};
response.send(JSON.stringify(data));
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
2.9 同源策略
同源策略(Same-Origin policy)是一种约定,由Netscape公司1995年引入到浏览器的,是浏览器最核心也是最基本的安全功能,现所有支持JavaScript的浏览器都会使用这个策略
若缺少同源策略,浏览器很容易受到XSS、CSFR等攻击
同源是指:协议+域名+端口,三者完全相同,而违背同源策略便是跨域
<!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>
<h1>尚硅谷</h1>
<button>点击获取用户数据</button>
<script>
const btn =document.querySelector('button');
btn.onclick = function(){
const xhr = new XMLHttpRequest();
// 这里因为满足同源策略,所以url可以简写
xhr.open('GET','/data');
// 发送
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.response);
}
}
}
}
</script>
</body>
</html>
const express = require('express');
// 创建应用对象
const app = express();
app.get('/home', (request,response)=>{
// 响应一个页面
response.sendFile(__dirname + '/index.html');
});
app.get('/data',(reqeust,response)=>{
response.send('用户数据');
});
app.listen(9000, ()=>{
console.log('服务已经启动...');
})
效果图
![](https://img-blog.csdnimg.cn/img_convert/65c44d01a8e0705b237c6d7bf4d71f49.png)
3.0 JSONP的实现原理
JSONP简介
JSONP(JSON with Padding) 是一个非官方的跨域解决方案
JSONP(JSON with Padding) 是json的一种“使用模式”,可以让网页从别的域名(网站)获取资料,即跨域读取数据
JSONP的实现原理
由于浏览器同源策略限制,网页无法通过AJAX请求非同源的接口数据
script标签不收浏览器同源策略的影响,可以通过src属性,请求非同源的js脚本数据
通过函数调用的形式,接收跨域接口响应回来的数据
简单理解就是将后端的响应数据作为函数参数,传递给前端的函数,前端函数调用后自然可以得到后端的响应数据
<!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: 300px;
height: 100px;
border: solid 1px #78a;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
// 处理数据
function handle(data) {
// 获取 result 元素
const result = document.getElementById('result');
result.innerHTML = data.name;
}
</script>
<script src="./app.js"></script>
<script src="http://localhost:8000/jsonp-server"></script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// jsonp服务
app.all('/jsonp-server',(request,response) => {
// response.send('console.log("hello jsonp")');
const data = {
name: '尚硅谷atguigu'
};
// 将数据转化为字符串
let str = JSON.stringify(data);
// 返回结果 `${变量}`是模板字符串的格式 `为反引号
response.send(`handle(${str})`);
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
效果图
![](https://img-blog.csdnimg.cn/img_convert/a1ef31fe802f46b5623e952cda7e3f41.png)
3.1 原生JSONP实践
记得启动服务端
<!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>
用户名:<input type="text" id="username">
<p></p>
<script>
// 获取 input 元素
const input = document.querySelector('input');
const p = document.querySelector('p');
// 声明 handle 函数
function handle(data) {
input.style.border = 'solid 1px #f00';
// 修改 p 标签的提示文本
p.innerHTML = data.msg;
}
// 绑定事件
input.onblur = function() {
// 获取用户的输入值
let username = this.value;
// 向服务器端发送请求,检测用户名是否存在
// 1. 创建 script 标签
const script = document.createElement('script');
// 2. 设置标签的 src 属性
script.src = 'http://localhost:8000/check-username';
// 3. 将 script插入文档中
document.body.appendChild(script);
}
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 用户名检测是否存在
app.all('/check-username',(request,response) => {
const data = {
exist: 1,
msg: '用户名已经存在'
};
// 将数据转化为字符串
let str = JSON.stringify(data);
// 返回结果
response.end(`handle(${str})`);
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
效果图
![](https://img-blog.csdnimg.cn/img_convert/43d62d01b3ec0d1896b4afbd0322d37a.png)
3.2 jQuery发送jsonp请求
效果图
![](https://img-blog.csdnimg.cn/img_convert/38f146bb30e42614344c532b4bc9483c.png)
<!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>jQuery-jsonp</title>
<style>
#result {
width: 300px;
height: 100px;
border: solid 1px #089;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
</head>
<body>
<button>点击发送 jsonp 请求</button>
<div id="result">
</div>
<script>
$('button').eq(0).click(function() {
$.getJSON('http://localhost:8000/jquery-jsonp-server?callback=?',function(data){
$('#result').html(`
名称: ${data.name}<br>
校区: ${data.city}
`)
})
});
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.all('/jquery-jsonp-server',(request,response) => {
const data = {
name: '尚硅谷',
city: ['北京','上海','深圳']
};
// 将数据转化为字符串
let str = JSON.stringify(data);
// 接收callback 参数
let cb = request.query.callback;
// 返回结果
response.end(`${cb}(${str})`);
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
3.3 设置CORS响应头实现跨域
CORS简介
CORS(Cross-Origin Resource Sharing), 跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要再客户端做任何特殊操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
CORS工作原理
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
效果图
![](https://img-blog.csdnimg.cn/img_convert/4e96a6b5bae0d561ca5027c240f2e9ff.png)
<!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>CORS</title>
<style>
#result{
width: 200px;
height: 100px;
border: solid 1px #90b;
}
</style>
</head>
<body>
<button>发送请求</button>
<div id="result"></div>
<script>
const btn = document.querySelector('button');
btn.onclick = function() {
// 创建对象
const xhr = new XMLHttpRequest();
// 初始化设置
xhr.open('GET','http://localhost:8000/cors-server');
// 发送
xhr.send();
// 绑定事件
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300){
// 输出响应体
console.log(xhr.response);
}
}
}
}
</script>
</body>
</html>
// 1. 引入express
const { request, response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.all('/cors-server',(request,response) => {
// 设置响应头
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5500')
response.send('hello CORS');
})
// 4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中......");
})
服务端设置了CORS后,可以跨域访问,除此还可以自设响应头和响应方法
![](https://img-blog.csdnimg.cn/img_convert/c1b1ad5145b165f3d5b6dfb1f854c66e.png)
结语
学习AJAX和jQuery非自愿,但学的时候肯定是用心且专注的,在粗略学完AJAX后还是有所收获,虽然过程中有部分内容没搞懂,因为部分知识还不到位,不过已经够了,毕竟主从搞后端的,后端都没学明白,前端先这样子吧
只能说为了人脸识别注册登录我付出太多了,一定要搞成