一言君
> > 学有所成,不计代价
视频来源:www.bilibili.com/video/BV1WC…
一、搭建服务端响应报文
//创建文件夹,vscode打开终端输入命令
npm init --yes
//生成的默认的package.json
npm install express # 本地安装
npm install express -g # 全局安装
//npm 命令安装常用的 Node.js web框架模块 express
node express基本使用.js
//运行js文件
http://localhost:8000/
//在浏览器访问端口号,可以看到服务端的响应;127.0.0.0.1:8000 冒号英文 无用
crtl+C
//终止之前的端口服务
http://localhost:8000/server
//打开一个AJAX get请求
二、前端界面如何发送AJAX请求
onreadystatechange
//on是当。。。时候 readystate表示状态 0 1 2 3 4
0未初始化、1open方法调用完毕、2send方法调用完毕、3服务端返回部分结果、4服务端返回全部结果
可以触发4次状态的改变change
//AJAX 页面发送GET请求代码!!!
btn.addEventListener('click', function () {
//1、创建对象
const xhr = new XMLHttpRequest();
//2、初始化
xhr.open('GET', 'http://localhost:8000/server?a=100&b=200&c=300');
//3、发送
xhr.send();
//4、事件绑定 处理服务端返回的结果
xhr.addEventListener('readystatechange', function () {
if (xhr.readyState === 4) {
//判断响应状态码
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;
}
}
})
})
//AJAX设置请求参数
xhr.open('GET', 'http://localhost:8000/server?a=100&b=200&c=300');
//AJAX 页面发送POST请求代码!!!
//我真的会谢谢,切记!!!!!!!如果没有报错,也觉得没问题但就是没结果,百分之99都是代码单词拼错或者漏写了
//AJAX POST请求设置请求体
xhr.send('123456');
//AJAX 设置请求头 setRequestHeader方法
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
三、页面发送请求4个步骤(⭐⭐⭐⭐)
1、创建页面请求对象
2、初始化对象
3、发送请求
4、事件绑定处理服务端返回的结果(状态码、状态字符串、所有的响应头、响应体)
代码如下:
const xhr = new XMLHttpResquest();
xhr.open('GET','URL');
xhr.send();
xhr.addEventListener('readystatechange',function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<300){
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.getAllResquestHeaders());
console.log(xhr.response);
}
}
})
四、 前后端数据交互
//服务端响应JSON数据 前端通过HTTP请求调用API接口,后端返回JSON或XML格式的数据
//不好意思,我是sb,真的今天咽痛眼痛脑子也没带出来,keydown人家是键盘事件,不是鼠标点击事件,一天天不知道在想什么
//后端代码
app.all('/server', (request, response) => {
//设置响应头 允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//设置响应头 允许自定义响应头
response.setHeader('Access-Control-Allow-Headers', '*');
//响应一个数据
const data = {
name: 'laohu'
};
//对象转换成字符串
let str = JSON.stringify(data);
//设置响应体
// response.send('HELLO AJAX POST');
response.send(str);
});
//前端代码
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8000/server');
//设置响应体数据类型
xhr.responseType = 'json';
xhr.send();
xhr.addEventListener('readystatechange', function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
//手动数据转换
// let data = JSON.parse(xhr.response);
// console.log(data);
//自动转换
result.innerHTML = data.name;
}
}
})
五、nodemon自动重启工具
npm install -g nodemon
//全局安装nodemon
nodemon server.js
//运行server.js文件
六、请求超时与网络异常
const xhr = new XMLHttpRequest();
//超时设置
xhr.timeout = 2000;
//超时回调
xhr.addEventListener('timeout', function () {
alert('网络异常,请稍后重试!')
})
//网络异常回调设置
//打开浏览器network网络设置改为offline断网
xhr.addEventListener('error', function () {
alert('您的网络似乎出现了一些问题!')
})
后端代码:
//延时响应
app.get('/delay', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
setTimeout(() => {
//设置响应体
response.send('延时响应');
}, 3000)
});
七、Ajax取消网络请求
//没有弹幕这日子真是过不下去 上次手动关了网络忘记改回来了doge
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
let x = null
const btns = document.querySelectorAll('button');
btns[0].addEventListener('click', function () {
x = new XMLHttpRequest();
x.open('GET', 'http://localhost:8000/delay');
x.send();
})
btns[1].addEventListener('click', function () {
x.abort();
})
</script>
</body>
八、Ajax请求重复的问题
<body>
<button>点击发送</button>
<script>
let x = null;
let isSending = false; //标识变量;是否正在发AJAX请求
const btn = document.querySelector('button');
btn.addEventListener('click', function () {
if (isSending) x.abort();
x = new XMLHttpRequest();
isSending = true;
x.open('GET', 'http://localhost:8000/delay');
x.send();
x.addEventListener('readystatechange', function () {
if (x.readyState === 4) {
isSending = false;
}
})
})
</script>
</body>
九、jQuery发送Ajax请求
<body>
<div>
<button>GET</button>
<button>POST</button>
<button>ALL</button>
</div>
<script>
$('button').eq(0).click(function () {
$.get('http://localhost:8000/jquery-server', { a: 100, b: 200 }, function (data) {
console.log(data);
}, 'json');
})
$('button').eq(1).click(function () {
$.post('http://localhost:8000/jquery-server', { a: 100, b: 200 }, function (data) {
console.log(data);
})
})
$('button').eq(2).click(function () {
$.ajax({
url: 'http://localhost: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>
十、Axios发送AJAX请求
const btns = document.querySelectorAll('button');
//配置baseURL
axios.defaults.baseURL = 'http://localhost:8000';
btns[0].addEventListener('click', function () {
axios.get('/axios-server', {
//url参数
params: {
id: 100,
vip: 7
},
//请求头信息
headers: {
name: 'woful',
age: '100000'
}
}).then(value => {
console.log(value);
});
});
btns[1].addEventListener('click', function () {
axios.post('/axios-server', {
username: 'admin',
password: 'admin'
}, {
//url参数
params: {
id: 200,
vip: 9
},
//请求头信息
headers: {
height: 100,
weight: 100
},
}).then(value => {
console.log(value);
});
});
十一、Axios函数发送AJAX请求
btns[2].addEventListener('click', function () {
axios({
method: 'POST',
//url
url: '/axios-server',
//url参数
params: {
vip: 22,
level: 33
},
//头信息
headers: {
a: 66,
b: 66
},
//请求体参数
data: {
username: "admin",
password: "admin"
}
}).then(response => {
console.log(response);
});
});
十二、fetch函数发送AJAX请求
const btn = document.querySelector('button');
btn.addEventListener('click', function () {
fetch('http://localhost:8000/fetch-server?vip=19', {
method: 'POST',
headers: {
name: 'howlong'
},
body: 'username=admin&password=admin'
}).then(response => {
// return response.text();
return response.json();
}).then(response => {
console.log(response);
});
})
十三、同源策略
同源:协议、域名、端口号必须完全相同
跨域:违背同源策略就是跨域
代码:
//笑死,多亏弹幕救人一命
response.sendFile(__dirname + '/index.html');
dirname前面两个下划线
十四、jsonp实现原理
[nodemon] app crashed - waiting for file changes before starting...
//这个报错我记得是重启解决的
//很好又少了个斜杠,还半天没发现,这个路由路径有问题,醉了
//html代码
<body>
<div class="result"></div>
<script>
function handle(data) {
const result = document.querySelector('.result');
result.innerHTML = data.name;
}
</script>
<!-- <script src="http://127.0.0.1:5500/%E4%BB%A3%E7%A0%81/7-%E8%B7%A8%E5%9F%9F/2-JSONP/js/app.js"></script> -->
<script src="http://localhost:8000/jsonp-server"></script>
</body>
//server.js代码
app.all('/jsonp-server', (request, response) => {
const data = {
name: 'nidaye'
};
let str = JSON.stringify(data);
response.end(`handle(${str})`);
response.send("console.log('hello jsonp')");
});
//jsonp实现原理就是script标签可以跨域,但是它拿到的数据是函数调用返回的结果
十五、原生jsonp实践
//html代码
<body>
用户名:<input type="text" id="username">
<p></p>
<script>
const input = document.querySelector('#username');
const p = document.querySelector('p');
function handle(data) {
input.style.border = '1px solid #f00';
p.innerHTML = data.msg;
}
input.addEventListener('blur', function () {
let username = this.value;
const script = document.createElement('script');
script.src = 'http://localhost:8000/check-username'; //jsonp实现跨域
document.body.appendChild(script);
})
</script>
</body>
//server.js代码
app.all('/check-username', (request, response) => {
const data = {
exist: 1,
msg: '用户名已经存在'
};
let str = JSON.stringify(data);
response.end(`handle(${str})`);
});
十六、jQuery发送jsonp请求
//html代码
<body>
<button>点击发送jQuery-jsonp请求</button>
<div class="result"></div>
<script>
$('button').eq(0).click(function () {
$.getJSON('http://localhost:8000/jquery-jsonp-server?callback=?', function (data) {
console.log(data);
$('.result').html(
`名称:${data.name}<br>
校区:${data.city}
`
)
});
})
</script>
</body>
//server.js代码
app.all('/jquery-jsonp-server', (request, response) => {
const data = {
name: 'xiaozhu',
city: ['上海', '北京', '深圳']
};
let str = JSON.stringify(data);
let cb = request.query.callback;
response.end(`${cb}(${str})`); //注意这里不要写错了
});
十七、设置CORS响应头实现跨域
//html代码
<body>
<button>点击发送请求</button>
<div class="result"></div>
<script>
const btn = document.querySelector('button');
const result = document.querySelector('.result');
btn.addEventListener('click', function () {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8000/cors-server');
xhr.send();
xhr.addEventListener('readystatechange', function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
})
})
</script>
</body>
//server.js代码
app.all('/cors-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*'); //就是之前一直写的这句话帮助实现跨域
response.send('hello cors');
});
十八、一些说明
1、Ajax:Asynchronous Javascript And XML;
即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
传输的数据可以是text纯文本,但是更常用的是xml,现在我们最经常使用就是json。
页面可以不用刷新就可以得到服务器返回的结果,也就是局部刷新。
2、axios可以看成Ajax+Promise
3、前后端交互的概念
前端和后端交互一般通过HTTP请求和响应来进行。前端通过浏览器向后端发送请求,后端收到请求后进行处理并返回响应,前端接收响应后进行相应的处理。
具体的交互方式可以有以下几种:
AJAX:前端通过JavaScript发起异步请求,向后端发送数据并接收响应,然后在页面上动态更新数据。
表单提交:前端通过表单提交数据,后端接收表单数据并进行处理,返回响应结果。
WebSocket:前端和后端通过WebSocket建立长连接,可以实现实时通信。
RESTful API:前后端通过定义好的API接口进行交互,前端通过HTTP请求调用API接口,后端返回JSON或XML格式的数据。