1.原生AJAX
1.1 AJAX介绍
- 异步的JS和XML.
- 无刷新获取数据.
- 不是编程语言,是将享有的标准组合在一起使用的新方式
1.2 XML 介绍
- XML 可拓展标记语言
- XML 被设计用来传输和存储数据
- XML和HTML类似 不用的是HTML都是预定义标签,而XML中没有预定义标签。
1.3 AJAX的特点
优点
- 无刷新获取数据
- 根据用户时间更新页面内容
缺点
- 没有浏览记录不能回退
- 存在跨域问题
- SEO不友好
2.HTPP协议
HTTP协议【超文本传输协议】协议详细规定了浏览器和万维网服务器之间互相通信的规则。
3.Express基本使用
// 1. 引入express
const { response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是请求报文的封装
// response 是对相应报文的封装
app.get('/',(request,response)=>{
// 设置响应
response.send('hellow express');
});
// 4. 监听端口启动服务
app.listen(8000,()=>{
console.log('服务启动 ,8000端口监听中');
});
如果下次要使用8000端口 需要到node按ctrl+C 关闭终端
4.HTML向服务端发送请求
4.1 发送GET与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>AJAX GET 请求</title>
</head>
<style>
#result {
width: 200px;
height: 200px;
border: 2px solid black;
}
</style>
<body>
<div id="result"></div>
<button id="btn">点击发送请求</button>
<script>
const btn = document.getElementById("btn");
const result = document.getElementById('result');
btn.onclick = function () {
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置请求方和和 url 设置参数可以传参
xhr.open('GET', 'http://localhost:8000/server?a=100&b=200&c=300');
// 或则POST
xhr.open('POST', 'http://localhost:8000/server?a=100&b=200&c=300');
// xhr.open('GET', 'http://localhost:8000/ie?t='+Date.now()); //ajax IE缓存的解决方法
// 3.发送
xhr.send('a=100&b=200&c=300'); //可以传递参数 等于号也可以是冒号 用的比较多
// 4.时间绑定 处理服务端返回的结果
// readstate 是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) {
// 处理结果 行 头 空行 体
// 1.响应行
// 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>
4.2 定义server.js文件引入express设置响应
// 1. 引入express
const { response } = require('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('hellow AJAX-GET');
});
// all 可以接收任意类型的请求
app.all('/server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
const data = {
name:'JiYvHan'
}
// 对对象进行字符串转换
let str = JSON.stringify(data);
// 设置响应体
response.send(str); //send只能接收字符串
});
//针对IE缓存
app.get('/ie', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send('hellow IE-4');
});
app.get('/delay', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
setTimeout(() => {
response.send('演示响应');
}, 3000);
});
// 4. 监听端口启动服务
app.listen(8000, () => {
console.log('服务启动 ,8000端口监听中');
});
4.3 JSON数据获取
<body>
<div id="result"></div>
<script>
// 绑定键盘按下事件
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){
// 处理服务端返回的结果
// console.log(xhr.response);
// result.innerHTML = xhr.response;
// 手动对数据转换
// let data = JSON.parse(xhr.response);
// console.log(data);
console.log(xhr.response);
// 自动转换
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
4.4 超时与网络异常
<script>
const btn = document.getElementById('btn');
const result = document.getElementById('result');
btn.addEventListener('click',function(){
// 发送请求
const xhr = new XMLHttpRequest();
// 超时设置2s
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = ()=>alert('网络异常,稍后再试!');
// 网络异常的回调
xhr.onerror = ()=>alert('网络异常');
// 初始化
xhr.open('GET','http://localhost:8000/delay');
// 发送
xhr.send();
// 事件绑定
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200&&xhr.status<300)
result.innerHTML = xhr.response;
}
}
})
</script>
4.5 AJAX取消请求
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
const btns = document.querySelectorAll('button');
let x = null;
btns[0].onclick = function(){
x = new XMLHttpRequest();
x.open('GET','http:localhost:8000/delay');
x.send();
}
// abort
btns[1].onclick = function(){
x.abort();
}
</script>
</body>
4.6 重复请求问题
<body>
<button>点击发送</button>
<script>
const btns = document.querySelectorAll('button');
let x = null;
// 标识变量
let isSending = false; // 是否正在发送AJAX请求
btns[0].onclick = function(){
// 判断表示变量
if(isSending) x.abort(); //如果正在发送则取消该请求,创建新的请求
x = new XMLHttpRequest();
// 修改表示变量的值
isSending = true;
x.open('GET','http:localhost:8000/delay');
x.send();
x.onreadystatechange = function(){
// 状态为4 成功发送请求时
if(x.readyState === 4){
// 修改表示变量
isSending = false;
}
}
}
</script>
</body>
2. JQuery发送AJAX请求
<body>
<div class="contaniner">
<h2>发送请求</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:localhost:8000/jQuer-server',{a:100,b:200},function(data){
console.log(data);
},'json');
})
$('button').eq(2).click(function(){
$.ajax({
// url
url:'http:localhost:8000/jQuer-server',
// 参数
data:{a:100,b:200},
// 请求类型
type:'GET',
// 响应体结果
dataType:'json',
// 成功的回调函数
success:function(data){
console.log(data);
},
timeout:2000,
error:function(){
console.log('error');
},
// // 头信息
// headers:{
// c:300,
// d:400
// }
})
})
</script>
</body>
// 1. 引入express
const { response } = require('express');
const express = require('express');
// 2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是请求报文的封装
// response 是对相应报文的封装
// jquery 服务
app.all('/jQuer-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
const data = {name:'jiyvhan'};
response.send(JSON.stringify(data));
});
3. axios发送AJAX请求
3.1 server.js部分
app.all('/axios-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
// 设置响应体
const data = {name:'jiyvhan'};
response.send(JSON.stringify(data));
});
3.2 html发送请求页面
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.js"></script>
<body>
<button>GET</button>
<button>POST</button>
<button>AJAX</button>
<script>
const btns = document.querySelectorAll('button');
// 配置baseURL
axios.defaults.baseURL = 'http://localhost:8000/'
btns[0].onclick = function () {
// get请求
axios.get('axios-server', {
// url 参数
params: {
id: 100,
vip: 7
},
// 请求头信息
headers: {
name: 'jiyuhan',
age: 22
}
}).then(value => {
console.log(value);
})
}
btns[1].onclick = function () {
// get请求
axios.post('axios-server',{
// 请求体
username: 'admin',
password: 'admin'
}, {
// url 参数
params: {
id: 200,
vip: 9
},
// 请求头信息
headers: {
height: 165,
width: 200
}
})
}
btns[2].onclick = function(){
axios({
// 请求方法
method:'POST',
// url
url:'axios-server',
// url 参数
params:{
vip:10,
level:10
},
// 头信息
headers:{
a:12,
b:2
},
// 请求体参数
data:{
username:'admin',
password:'admin'
}
}).then(response=>{
console.log(response);
// 响应状态码
console.log(response.status);
// 响应状态字符串
console.log(response.statusText);
// 响应头信息
console.log(response.headers);
// 响应体
console.log(response.data);
})
}
</script>
</body>
4. fetch函数发送AJAX请求
4.1 html发送部分
<body>
<button>AJAX请求</button>
<script>
const btn = document.querySelector("button");
btn.onclick = function(){
// url 可选配置项
fetch('http://localhost:8000/fetch-server?vip=10',{
// 请求方法
method:'POST',
// 请求头
headers:{
name:'jiyuhan'
},
// 请求体
body:'username=admin&password=admin'
}).then(response=>{
return response.json();
}).then(response=>{
console.log(response);
})
}
</script>
</body>
4.2 server.js部分
// fetch 服务
app.all('/fetch-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
// 设置响应体
const data = {name:'jiyvhan'};
response.send(JSON.stringify(data));
});
5. 跨域
5.1 同源策略
同源策略(Same-Origin Policy)最早是由 Netscape公司提出,是浏览器的一种安全策略.
同源: 协议 域名 端口号 必须完全相同
违背同源策略就是跨域
端口都是9000 属于同源 可以直接发送AJAX请求
<body>
<h1>同源策略</h1>
<button>点击获取用户数据</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
const x = new XMLHttpRequest();
// 这里因为是满足同源策略的所以URL可以简写
x.open('GET','/data');
// 发送
x.send();
//
x.onreadystatechange = function(){
if(x.readyState === 4){
if(x.status>=200&&x.status<300){
console.log(x.response);
}
}
}
}
</script>
</body>
const express = require("express");
const { response } = require("express");
const { request } = require("express");
const app = express();
app.get('/home',(request,response)=>{
// 响应一个页面
response.sendFile(__dirname + '/同源策略.html');
});
app.get('/data',(request,response)=>{
response.send('用户数据');
})
app.listen(9000,()=>{
console.log('服务已经启动...');
})
5.2 如果解决跨域
JSONP 是什么
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明
才智开发出来,只支持get 请求。
在网页有一些标签天生具有跨域能力,比如:img link iframe script。
JSONP 就是利用script 标签的跨域能力来发送请求的。
1.动态的创建一个script 标签
var script = document.createElement("script");
2.设置script 的src,设置回调函数
script.src = "http://localhost:3000/testAJAX?callback=abc";
function abc(data) {
alert(data.name);
3.将script 添加到body 中
document.body.appendChild(script);
4.服务器中路由的处理
router.get("/testAJAX" , function (req , res) {
console.log("收到请求");
var callback = req.query.callback;
var obj = {
name:"孙悟空",
age:18
}
res.send(callback+"("+JSON.stringify(obj)+")");
});
5. JSONP实践
5.1 HTML
<body>
用户名: <input type="text" id="username">
<p></p>
<script>
const input = document.querySelector('input');
const p = document.querySelector('p');
// 声明handle函数
function handle(data){
input.style.border = "1px solid red";
// 修改P文本
p.innerHTML = data.msg;
}p
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>
5.2 JS
/ 用户名检测是否存在
app.all('/check-username',(request,response)=>{
const data ={
exist:1,
msg:'用户名已经存在'
};
// 将数据转换为字符串
let str = JSON.stringify(data);
// 返回结果
response.end(`handle(${str})`);
})