个人主页:花棉袄
本章内容:【前端核心五:AJAX】学习视频推荐
✍ 版权: 本文由【花棉袄】原创在CSDN首发需要转载请联系博主
AJAX
:全称为Asynchronous JavaScript And XML,就是异步的JS
和XML
通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据
AJAX不是新的编程语言
,而是一种将现有的标准 组合在一起使用的新方式
AJAX 的优点
可以无需刷新页面而与服务器端进行通信
允许你根据用户事件来更新部分页面内容
AJAX 的缺点
没有浏览历史,不能回退
存在跨域问题(同源)
SEO(Search Engine Optimization,搜索引擎优化)不友好,爬虫无法爬取
HTTP(hypertext transport protocol)协议「超文本传输议」
协议详细规定了浏览器和万维网服务器之间互相通信的规则
请求行
请求类型:GET/POST/PUT/DELETE/PATCH
URL 路径:s?ie=utf-8
HTTP 协议版本:HTTP/1.1
请求头
Host: atguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded
User-Agent: chrome 83
…
请求空行:固定格式,必须有
请求体:GET请求,请求体为空;POST请求,请求体可以不为空
username=admin&password=admin
响应行
HTTP 协议版本:HTTP/1.1
响应状态码:200/404/500
响应状态字符串:OK/Not Found/Internal Server Error,与响应状态码对应
响应头
Content-Type: text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip
…
响应空行 :固定格式,必须有
响应体
1xx
:Informational(信息性状态码) 请求正在处理
2xx
:Success(成功状态码) 请求正常处理完毕
3xx
:Redirection(重定向) 需要进行附加操作以完成请求
4xx
:Client error(客户端错误) 客户端请求出错
5xx
:Server Error(服务器错误) 服务器处理请求出错
200
OK 请求成功
302
Found 请求资源的 URL 被暂时修改到 Location 提供的 URL
304
Not Modified 资源未变更
308
Permanent Redirect 永久重定向
400
Bad Request 请求语法有问题,服务器无法识别
401
UnAuthorized 客户端未授权该请求
403
Forbidden 服务器拒绝响应
404
Not Found URL 无效或者 URL 有效但是没有资源
500
Internal Server Error 服务器内部错误
502
Bad Gateway 服务器作为网关使用时,收到上游服务器返回的无效响应
503
Service Unavailable 无法服务,一般发生在因维护而停机或者服务过载
504
Gateway Timeout 网关超时
505
Http Version Not Supported 发出的请求http版本服务器不支持
安装 Node.js
# 初始化
npm init --yes
# 安装express框架
npm i express
// 1、引入express
// const express = require('express');
import express from 'express';
// 2、创建应用对象
const app = express();
// 3、创建路由规则
// request 请求报文的封装
// response 响应报文的封装
app.get('/', (request, response) => {
// 设置响应
response.send('Hello Express');
});
// 4、监听端口启动服务
app.listen(8000, () => {
console.log("服务已经启动,8000 端口监听中...");
});
键入命令 node js文件名
出现服务已经启动,8000 端口监听中…字样,说明启动成功
我们打开浏览器,访问 http://127.0.0.1:8000,出现Hello Express字样
<!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>
<style>
#result {
width: 200px;
height: 100px;
border: 1px solid #90b;
}
</style>
<button>点击发送</button>
<div id="result"></div>
</body>
</html>
// 1、引入express
// const express = require('express');
import express from '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 端口监听中...");
});
创建对象
const xhr = new XMLHttpRequest();
初始化
xhr.open('GET', 'http://127.0.0.1:8000/server');
发送
xhr.send();
事件绑定,处理服务器端返回的结果
xhr.onreadystatechange = function () {...}
<!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>
</head>
<body>
<style>
#result {
width: 200px;
height: 100px;
border: 1px solid #90b;
}
</style>
<button>点击发送</button>
<div id="result"></div>
<script>
const result = document.getElementById('result');
const button = document.getElementsByTagName("button")[0];
button.onclick = function () {
// 1、创建对象
const xhr = new XMLHttpRequest();
// 2、初始化
xhr.open('GET', 'http://127.0.0.1:8000/server');
// 3、发送
xhr.send();
// 4、事件绑定,处理服务器端返回的结果
xhr.onreadystatechange = function () {
// 服务端返回所有结果
if (this.readyState === 4) {
// 2xx 成功
if (this.status >= 200 && this.status < 300) {
// 状态码、状态字符串
console.log("status:" + this.status); // 200
console.log("statusText:" + this.statusText); // OK
// 响应头
console.log("Headers:" + this.getAllResponseHeaders()); // content-length: 13 content-type: text/html; charset=utf-8
// 响应体
console.log("response:" + this.response); // Hello Express
// 将响应体内容设置为文本
result.innerHTML = this.response;
}
}
}
};
</script>
</body>
</html>
GET 设置请求行
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
// 1、引入express
// const express = require('express');
import express from 'express';
// 2、创建应用对象
const app = express();
// 3、创建路由规则
// request 请求报文的封装
// response 响应报文的封装
app.post('/server', (request, response) => {
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('Hello AJAX');
});
// 4、监听端口启动服务
app.listen(8000, () => {
console.log("服务已经启动,8000 端口监听中...");
});
<script>
const result = document.getElementById('result');
result.addEventListener('mouseover', function () {
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://127.0.0.1:8000/server');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState === 4 && this.status >= 200 && this.status < 300) {
result.innerHTML = this.response;
}
};
});
</script>
POST 设置请求体
xhr.send('a=100&b=200&c=300');
设置请求头信息
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
自定义的请求头
xhr.setRequestHeader('name', 'atguigu');
app.all('/server', (request, response) => {
// 设置响应头,允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头,允许任意类型的头信息
response.setHeader('Access-Control-Allow-Headers', '*');
// 设置响应体
response.send('Hello Express');
});
const data = {
name:'Hello Ajax'
}
let str = JSON.stringify(data);
response.send(str);
手动转换数据
let response = this.response;
console.log(typeof response); // string
data = JSON.parse(response);
result.innerHTML = data.name;
官网地址:https://www.npmjs.com/package/nodemon
安装命令:npm install -g nodemon
启动命令:nodemon xxx.js替代node xxx.js
优点:修改服务端代码不用每次手动shutdown重启
# js文件
setTimeout(() =>{
response.send('Hello Ajax');
}, 2000);
# html文件
// 设置超时时间
xhr.timeout = 1000;
// 设置超时回调
xhr.ontimeout = () => {
alert('请求超时!');
};
# html 文件
// 设置网络异常回调
xhr.onerror = () => {
alert("网络异常");
};
abort()方法:手动取消请求
const btns = document.getElementsByTagName('button');
const btn1 = btns[0];
const btn2 = btns[1];
let xhr = null;
btn1.addEventListener('click', () => {
xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/server-timeout');
xhr.send();
});
btn2.addEventListener('click', () => {
xhr.abort();
});
如果服务器响应相对比较慢,而用户因为得不到响应而频繁地点击按钮
浏览器短时间内会向服务器发起大量重复的请求
服务器就要对这些请求进行频繁的处理
服务器端的压力就会非常的大
const btns = document.getElementsByTagName('button');
let xhr = null;
// 标识是否正在发送 AJAX 请求
let isSending = false;
btns[0].addEventListener('click', () => {
// 若上一个请求尚未完成,则手动取消请求
if (isSending) {
xhr.abort();
}
xhr = new XMLHttpRequest();
isSending = true;
xhr.open('GET', 'http://127.0.0.1:8000/servertimeout');
xhr.send();
xhr.onreadystatechange = () => {
// 请求响应完毕后,修改变量标识
if (xhr.readyState === 4) {
isSending = false;
}
};
});
jQuery 脚本
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
bootstrp 脚本
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet">
$.get(url,[data],[callback],[type])
url
:请求的 URL 地址
data
:请求携带的参数
callback
:载入成功时回调函数
type
:设置返回内容格式,xml,html,script,ison,text,_default
btns.eq(0).click(() => {
$.get('http://127.0.0.1:8000/server-jquery', { a: 100, b: 200 }, (data) => {
console.log(typeof data, data); // object {name: "Hello jquery"}
}, 'json');
});
$.post(url,[data],[callback],[type])
url
:请求的 URL 地址
data
:请求携带的参数
callback
:载入成功时回调函数
type
:设置返回内容格式,xml,html,script,ison,text,_default
btns.eq(1).click(() => {
$.post('http://127.0.0.1:8000/server-jquery', { a: 100, b: 200 }, (data) => {
console.log(typeof data, data); // string {name: "Hello jquery"}
},"json");
});
$.ajax({
// 请求地址
url: 'http://127.0.0.1:8000/server-jquery',
// 请求参数
data: { a: 100, b: 200 },
// 请求类型
type: 'GET',
// 响应体类型
dataType: 'json',
// 成功回调
success: data => {
console.log(typeof data, data); // string {name: "Hello jquery"} 开启dataType后:object {name: "Hello jquery"}
},
// 超时时间
timeout: 1000,
// 失败的回调
error: () => {
alert('出错了');
},
// 头信息
headers: {
c: 300,
d: 400
}
});
axios#get(url[,config])
axios.defaults.baseURL = 'http://127.0.0.1:8000/';
axios.get('server-axios', {
// 请求参数
params: {
a: 100,
b: 200
},
// 请求头
headers: {
c: 300,
d: 400
}
}).then(value => {
console.log(value);
});
axios#post(url[,data[,config]])
axios.post('server-axios', {
// 请求体
e: 500,
f: 600
}, {
// 请求参数
params: {
a: 100,
b: 200
},
// 请求头
headers: {
c: 300,
d: 400
}
}).then(value => {
console.log(value);
});
axios(url[, config])
axios({
method: 'POST',
url: 'server-axios',
// 请求参数
params: {
a: 100,
b: 200
},
// 请求头
headers: {
c: 300,
d: 400
},
// 请求体
data: {
e: 500,
f: 600
},
// 响应体类型
dataType: 'json'
}).then(response => {
console.log(response.status); // 200
console.log(response.statusText); // OK
console.log(response.headers); // {content-length: "22", content-type: "text/html; charset=utf-8"}
console.log(typeof response.data, response.data); // object {name: "Hello axios"}
});
fetch('http://127.0.0.1:8000/server-fetch?a=100&b=100', {
// 请求方法
method: 'POST',
// 请求头
headers: {
c: 300,
d: 400
},
// 请求体
body: 'e=500&f=600'
}).then(response => {
console.log(response);
});
...
.then(response => {
return response.text();
}).then(response => {
console.log(typeof response, response); // string {"name":"Hello fetch"}
});
...
.then(response => {
return response.json();
}).then(response => {
console.log(typeof response, response); // object {"name":"Hello fetch"}
});
<!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>
<style>
</style>
<button>点击发送</button>
<div id="result"></div>
用户名:<input type="text" id="username">
<p></p>
<script>
//声明handle函数
function handle(data) {
var input = document.querySelector('input');
input.style.border = "solid 1px #f00";
//修改p标签的提示文本
var p = document.querySelector('p');
p.innerHTML = data.msg;
}
</script>
<script>
const input = document.querySelector('input');
input.onblur = () => {
let username = this.username;
// 1、创建一个 script 标签
var script = document.createElement('script');
// 2、设置 src 属性
script.src = 'http://127.0.0.1:8000/check-username';
// 3、将 script 插入文档中
document.body.appendChild(script);
};
</script>
</body>
</html>
// 1、引入express
// const express = require('express');
import express from '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 端口监听中...");
});
$.getJSON(url,[data],[fn])
url:发送请求地址
data:待发送 key/value 参数
callback:载入成功时回调函数
<button>点击发送请求</button><br><br>
<div id="result"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$('button').eq(0).click(() => {
$.getJSON('http://127.0.0.1:8000/server-jsonp-jquery?callback=?', data => {
$('#result').html(data.msg);
});
});
</script>
app.all('/server-jsonp-jquery', (request, response) => {
const data = {
exist: 1,
msg:'用户名已存在'
};
let str = JSON.stringify(data);
response.end(`(${str})`);
});
// 接收callback参数
var cb = request.query.callback;
response.end(`${cb}(${str})`);
// 设置响应头,允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
Access-Control-Allow-Origin 指定了允许访问该资源的外域 URI
Access-Control-Expose-Headers 让服务器把允许浏览器访问的头放入白名单
Access-Control-Max-Age 指定了 preflight 请求的结果能够被缓存多久
Access-Control-Allow-Credentials 是否允许浏览器读取 response 的内容
Access-Control-Allow-Methods 指明了实际请求所允许使用的 HTTP 方法
Access-Control-Allow-Headers 指明了实际请求中允许携带的首部字段
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-A1low-Method", "*");
全栈小狐狸的逆袭之路: Java学习路线
前端核心:JavaScript
前端核心:jQuery
前端核心:Bootstrap
前端核心:AJAX