目录
七、jQuery与AJAX、Axios与AJAX(可用BootCDN引入jQuery、Axios)
一、XML
1. XML(可扩展标记语言):被设计用来传输和存储数据;
2. XML:支持自定义标签,无预定义标签。
3. HTML和XML的区别
1)HTML:超文本标记语言,用于显示数据,不区分大小写;
XML:可扩展标记语言,用于传输数据,区分大小写;
2)HTML:预定义标记;
XML:自定义标记。
二、AJAX特点
1. 优点:
1)可以直接与服务器端进行通信,而不需要刷新页面;
2)允许根据用户事件来更新部分内容页面;
2. 缺点:
1)没有浏览历史,不可回退;
2)存在跨域问题(即是否同源);
3)对SEO(SEO:搜素引擎优化)不友好。
三、HTTP协议
1. HTTP协议(超文本传输协议):详细规定了浏览器和万维网服务器之间互相通信的规则;
主要约定的内容:
请求:浏览器发送给服务器;
请求报文:浏览器发送给服务器的内容;
响应:服务器端返回给浏览器;
响应报文:服务器端返回给浏览器的内容。
2. 请求报文:
1)格式:
行 GET(请求类型)/ url路径 HTTP/1.1(HTTP版本)
头 Host:atguigu.com
Cookie:name=guigu
(格式:名字+:+空格+值)
空行(必须要)
体
2)头的作用:告知服务器请求体的类型
设置url的方式:地址分割用 ?,多个值用 & 连接。
3. 响应报文:
1)格式:
行 HTTP/1.1(HTTP版本) 响应状态码 响应状态字符串(与状态码对应)
头 Content-Type:text/html;charset=utf-8
Content-length:2048
(格式:名字+:+空格+值)
空行(必须要)
体(放html内容)
2)头的作用:对响应体内容做相关描述。
三、Express服务端框架
1. express:基于 node.js 平台;
2. 安装步骤:
文件最外层启动终端 -> 输入 npm init --yes -> 输入 npm i express
安装 nodemon:
npm install -g nodemon
3. 使用步骤:
1)引入express:const express = require(‘express’);
2)创建应用对象:const app = express();
3)创建路由规则:
request:对请求报文的封装;
response:对响应报文的封装。
app.get(‘/’,(request,response) => {
response.send(‘HELLO’);
});
4)监听端口启动服务:
app.listen(8000,()=> {
console.log(“服务已经启动,8000端口监听中...”);
})
5)在终端输入 node + 文件名(文件名一定要写上后缀名!!)
四、Express服务端框架简单实现代码
实现点击按钮,将响应体内容显示在一个盒子中
1. express服务端框架代码:
//1.引入express
const { request, response } = require("express");
const express = require("express");
const res = require("express/lib/response");
//2.创建应用对象
const app = express();
//3.创建路由规则
app.all("/json-server", (request, response) => {
//设置响应头 设置允许跨域
response.setHeader("Access-Control-Allow-Origin", "*");
//设置头 可以任意名
response.setHeader("Access-Control-Allow-Headers", "*");
//设置响应体
//响应一个数据
const data = {
name: "sehun",
};
//对对象进行字符串转换
let str = JSON.stringify(data);
//send 只能接收字符串或者buffer
response.send(str);
});
//app.all() 可以接收任意类型的请求
2. 页面代码:
<body>
<input type="button" value="点击发送请求" id="button" />
<div class="result" id="result"></div>
</body>
<script>
//获取button元素
const btn = document.getElementById("button");
const result = document.querySelector(".result");
btn.onclick = function () {
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化 设置请求方法和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
// 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.innerHTML = xhr.response;
}
}
};
console.log("test");
};
</script>
3. 实现结果:
五、IE缓存问题及超时与网络异常
1. 什么是IE缓存问题?
IE浏览器会对ajax请求的结果做一个缓存,不能及时反应ajax请求的变化,影响时效性;
2. 解决方法:在 open() 初始化设置 url 时,加 ?t=" + Date.now()
xhr.open("GET", "url地址?t=" + Date.now());
3. 具体代码:
<body>
<input type="button" value="点击发送请求" id="button" />
<div class="result" id="result"></div>
</body>
<script>
const btn = document.querySelector("#button");
const result = document.querySelector(".result");
btn.addEventListener("click", () => {
console.log("test");
const xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8000/ie?t=" + Date.now());
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
};
});
</script>
//针对 IE缓存 的规则
app.get("/ie", (request, response) => {
//设置响应头 设置允许跨域
response.setHeader("Access-Control-Allow-Origin", "*");
//设置响应体
response.send("Hello IE qaq");
});
4. 超时(自动取消请求)与网络异常处理:
1)进行延时设置, 设置 timeout 并在请求中使用 ontimeout 回调函数,当超过 timeout 所规定的时间时,则取消请求并执行 ontimeout 的函数内容;
2)使用 onerror 判别网络是否出现问题;
5. 具体实现:
<body>
<input type="button" value="点击发送请求" id="button" />
<div class="result" id="result"></div>
</body>
<script>
const btn = document.querySelector("#button");
const result = document.querySelector(".result");
btn.addEventListener("click", () => {
console.log("test");
const xhr = new XMLHttpRequest();
//延时设置 意味着在3/2s内没有结果请求就取消
xhr.timeout = 1500;
//超时回调
xhr.ontimeout = () => {
alert("网络异常,请稍后再试qaq");
};
//网络异常回调
xhr.onerror = () => {
alert("您的网络似乎出现了一些问题");
};
xhr.open("GET", "http://127.0.0.1:8000/delay");
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
};
});
</script>
//延时响应规则
app.all("/delay", (request, response) => {
//设置响应头 设置允许跨域
response.setHeader("Access-Control-Allow-Origin", "*");
//设置头 可以任意名
response.setHeader("Access-Control-Allow-Headers", "*");
//设置定时器
setTimeout(() => {
//设置响应体
response.send("Hello 延时响应");
}, 2000);
});
6. 结果如下:
1) 超时:
六、手动取消请求及请求重复发送问题
1. 取消请求(手动):利用 abort 手动取消请求
2. 代码实现:
<body>
<input type="button" value="点击发送" id="btn1" />
<input type="button" value="点击取消" id="btn2" />
</body>
<script>
const btn1 = document.querySelector("#btn1");
const btn2 = document.querySelector("#btn2");
let x = null;
btn1.onclick = () => {
x = new XMLHttpRequest();
x.open("GET", "http://127.0.0.1:8000/delay");
x.send();
};
// abort 取消 -> 手动取消
btn2.onclick = () => {
x.abort();
};
</script>
3. 结果:
4. 请求重复发送问题:(避免服务器压力过大)
5. 代码实现
<body>
<input type="button" value="点击发送" id="btn" />
</body>
<script>
//获取元素
const btn = document.querySelector("#btn");
let x = null;
//标识变量
let sign = false; // 是否正在发送AJAX请求 true代表正在发送
btn.onclick = () => {
//判断标识变量
//如果正在发送,则取消该请求,创建一个新的请求
if (sign) {
x.abort();
}
x = new XMLHttpRequest();
//修改 标识变量的值
sign = true;
x.open("GET", "http://127.0.0.1:8000/delay");
x.send();
//判断请求是否完成
x.onreadystatechange = () => {
if (x.readyState === 4) {
//修改标识变量
sign = false;
}
};
};
</script>
6. 结果:
七、jQuery与AJAX、Axios与AJAX(可用BootCDN引入jQuery、Axios)
1. jQuery发送AJAX请求:GET、POST、通用型
2.代码:
<body>
<div class="container">
<h2 class="page-header">jQuery发送AJAX请求</h2>
<input type="button" value="GET" class="btn btn-primary" />
<input type="button" value="POST" class="btn btn-danger" />
<input type="button" value="通用型方法ajax" class="btn btn-info" />
</div>
</body>
<script>
$("input")
.eq(0)
.click(() => {
// 第一个参数代表 要发送给谁
// 第二个参数代表 要发送什么参数值
// 第三个参数 是一个回调
// 第四个参数 是响应体类型
$.get(
"http://127.0.0.1:8000/jquery-server",
{ a: 100, b: 200 },
(data) => {
console.log(data);
},
"json"
);
});
$("input")
.eq(1)
.click(() => {
// 第一个参数代表 要发送给谁
// 第二个参数代表 要发送什么参数值
// 第三个参数 是一个回调
$.post(
"http://127.0.0.1:8000/jquery-server",
{ a: 100, b: 200 },
(data) => {
console.log(data);
},
"json"
);
});
$("input")
.eq(2)
.click(() => {
$.ajax({
//url
url: "http://127.0.0.1:8000/jquery-server",
//参数
data: { a: 100, b: 200 },
//请求类型
type: "GET",
//响应体结果
dataType: "json",
//成功的回调
success: (data) => {
console.log(data);
},
//超时时间
timeout: 2000,
//失败的回调
error: () => {
console.log("error!");
},
});
});
</script>
//jquery 服务规则
app.all("/jquery-server", (request, response) => {
//设置响应头 设置允许跨域
response.setHeader("Access-Control-Allow-Origin", "*");
// 转换为json
const data = { name: "sehun" };
//设置响应体
//response.send("Hello jQuery AJAX");
response.send(JSON.stringify(data));
});
3. 结果:
4. Axios发送AJAX请求:GET、POST、通用型
5. 代码:
<body>
<input type="button" value="GET" />
<input type="button" value="POST" />
<input type="button" value="ajax" />
</body>
<script>
const btns = document.querySelectorAll("input");
//配置基本url
axios.defaults.baseURL = "http://127.0.0.1:8000";
btns[0].onclick = () => {
//get请求
axios
.get("/axios-server", {
//url 参数
params: {
id: 100,
vip: 7,
},
//请求头信息
headers: {
name: "sehun",
},
})
.then((value) => {
console.log(value);
});
};
btns[1].onclick = () => {
axios.post(
"/axios-server",
//请求体
{
username: "sehun",
password: "exo",
},
{
//url
params: {
id: 200,
vip: 9,
},
//请求头
headers: {
height: 180,
weight: 180,
},
}
);
};
btns[2].onclick = () => {
axios({
//请求方法
method: "POST",
//url
url: "/axios-server",
//url参数
params: {
vip: 10,
level: 30,
},
//请求头
headers: {
a: 100,
b: 200,
},
//请求体
data: {
username: "sehun",
password: "exo",
},
}).then((response) => {
console.log(response);
//响应状态码
console.log(response.status);
//响应状态字符串
console.log(response.statusText);
//响应头信息
console.log(response.headers);
//响应体
console.log(response.data);
});
};
</script>
//axios 服务规则
app.all("/axios-server", (request, response) => {
//设置响应头 设置允许跨域
response.setHeader("Access-Control-Allow-Origin", "*");
//设置头 可以任意名
response.setHeader("Access-Control-Allow-Headers", "*");
// 转换为json
const data = { name: "sehun" };
//设置响应体
//response.send("Hello jQuery AJAX");
response.send(JSON.stringify(data));
});
6. 结果:
八、fetch函数发送ajax请求
1. 利用fetch函数发送ajax请求,第一个参数为url,第二个参数为一个函数体
2. 代码:
<body>
<input type="button" value="ajax请求" />
</body>
<script>
const btn = document.querySelector("input");
btn.onclick = () => {
fetch("http://127.0.0.1:8000/fetch-server", {
//方法
method: "POST",
//请求头
headers: {
name: "sehun",
},
//请求体
body: "username=sehun&password=exo",
})
.then((response) => {
//return response.text();
return response.json();
})
.then((response) => {
console.log(response);
});
};
</script>
//fetch 服务规则
app.all("/fetch-server", (request, response) => {
//设置响应头 设置允许跨域
response.setHeader("Access-Control-Allow-Origin", "*");
//设置头 可以任意名
response.setHeader("Access-Control-Allow-Headers", "*");
// 转换为json
const data = { name: "sehun" };
//设置响应体
//response.send("Hello jQuery AJAX");
response.send(JSON.stringify(data));
});
3. 结果如下:
九、同源策略
(一)同源策略(ajax默认遵循同源策略)
1. 最早由Netscape公司提出,是浏览器的一种安全策略;
2. 同源策略:网页的url与在网页中用ajax请求的url在协议、域名、端口号方面必须完全相同(即同一个来源/来自同一个服务器)
3. 跨域:违背同源策略;
4. 解决跨域问题:
1)JSONP
① 工作原理:借助页面的script标签进行跨域
② 调用返回的应该是一段js代码
③ 返回结果的形式是一个函数调用
注:函数的参数则是我们想给客户端返回的客户数据,前端需要提前说明!
2)CORS
① 跨域资源共享,官方的跨域解决方案
② 特点:不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求
③ 通过设置一个响应头解决
(二)具体代码
1. jsonp
1)代码:
<body>
<div class="result"></div>
<script>
function handle(data) {
//获取result元素
const result = document.querySelector(".result");
result.innerHTML = "发送给" + data.name;
}
</script>
</body>
<script src="http://127.0.0.1:8000/jsonp-server"></script>
//jsonp 服务规则 返回结果的形式是一个函数调用
//函数的参数则是我们想给客户端返回的客户数据 前端需要提前说明
app.all("/jsonp-server", (request, response) => {
//response.send('console.log("hello jsonp-server")');//返回js代码
const data = {
name: "sehunBBQ",
};
//将数据转换为字符串
let str = JSON.stringify(data);
//返回结果
//end 返回不会加响应头
response.end(`handle(${str})`);
});
2)结果:
2. jsonp实践:检测用户名是否存在
1)代码:
<body>
用户名:<input type="text" name="" id="username" />
<p></p>
</body>
<script>
//获取input
const text = document.querySelector("#username");
const p = document.querySelector("p");
//声明 handle 函数
function handle(data) {
//将边框颜色变为红色
text.style.border = "1px solid #f00";
//修改p标签的提示文本
p.innerHTML = data.msg;
}
//绑定事件
text.onblur = () => {
//获取用户的输入值
let username = this.value;
//向服务端发送请求 监测用户名是否存在
//1.创建 script 标签
const script = document.createElement("script");
//2.设置标签的 src 属性
script.src = "http://127.0.0.1:8000/check-username";
//3.将script 插入文档中
document.body.appendChild(script); // 将 script标签插入body最后
};
</script>
//检测用户名是否存在
app.all("/check-username", (request, response) => {
const data = {
exist: 1,
msg: "用户名已经存在",
};
let str = JSON.stringify(data);
response.end(`handle(${str})`);
});
2)结果:
3. jQuery发送jsonp请求
1)代码:
<script
crossorigin="anonymous"
src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"
></script>
<body>
<input type="button" value="点击发送jsonp请求" />
<div class="result"></div>
</body>
<script>
$("input")
.eq(0)
.click(() => {
//发送jsonp请求
//第一个参数:url !!!原本的url后要 + 一个参数-> ?callback=?
$.getJSON(
"http://127.0.0.1:8000/jquery-jsonp-server?callback=?",
(data) => {
$(".result").html(`
名称:${data.name}<br/>
校区:${data.city}
`);
}
);
});
</script>
//jquery 发送 jsonp请求
app.all("/jquery-jsonp-server", (request, response) => {
const data = {
name: "sehun❤",
city: ["首尔", "长安", "洛阳"],
};
//将数据转换成字符串
let str = JSON.stringify(data);
//接收callback参数
let cb = request.query.callback;
//返回结果
response.end(`${cb}(${str})`);
});
2)结果:
4. cors发送ajax请求
1)代码:
<body>
<input type="button" value="发送请求" class="btn" />
<div class="result"></div>
</body>
<script>
const btn = document.querySelector(".btn");
const result = document.querySelector(".result");
btn.onclick = () => {
const x = new XMLHttpRequest();
//初始化设置
x.open("GET", "http://127.0.0.1:8000/cors-server");
//发送
x.send();
//绑定事件
x.onreadystatechange = () => {
//判断
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
//输出响应体
console.log(x.response);
result.innerHTML = x.response;
}
}
};
};
</script>
//cros服务规则
app.all("/cors-server", (request, response) => {
//设置响应头
response.setHeader("Access-Control-Allow-Origin", "*");
response.send("hello CORS");
});
2)结果:
5. 同源
1)代码:
<body>
<h1>新の一年</h1>
<h2>永远热爱 吴世勋❤</h2>
<input type="button" value="点击即可世勋发送爱心" />
</body>
<script>
const btn = document.querySelector("input");
btn.onclick = () => {
const x = new XMLHttpRequest();
//因为这里是满足同源策略,所以 url 可以省略相同部分 进行简写
//会自动补全
x.open("GET", "/data");
//发送
x.send();
//
x.onreadystatechange = () => {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
console.log(x.response);
}
}
};
};
</script>
const { request, response } = require("express");
const express = require("express");
const app = express();
app.get("/index", (request, response) => {
//响应一个页面
response.sendFile(__dirname + "/index.html");
response.send("发射爱心 -> ❤");
});
app.get("/data", (request, response) => {
response.send("发射两个爱心 -> ❤");
});
app.listen(9000, () => {
console.log("世勋提醒你❤:服务已经启动!");
});