手撕ajax
/*
* @Author: Kongjingjing
* @Date: 2022-09-20 10:34:14
* @Description:
*/
const url = "/server";
let xhr = new xhrHttpRequest(); // 创建一个xhr对象 xhr
xhr.open("GET", url, true); // open方法创建一个http请求
xhr.responseType = "json"; // 请求头信息
xhr.setRequestHeader("Accept", "application/json");
// 发送请求
xhr.send(null);
xhr.onreadystatechange = function () {
// 状态监听函数
if (this.readyState !== 4) return;
if (this.status === 200) {
//请求成功
handle(this.response);
} else {
// 请求失败
console.log(this.statusText);
}
};
//请求失败时的监听函数
xhr.onerror = function () {
console.log(this.statusText);
};
promise封装
/**
* @Author: Kongjingjing
* @Date: 2022-09-20 11:11:34
* @Description: promise封装ajax
* @param {*} url 请求地址
*/
function getHttp(url) {
let promise = new promise((reslove, reject) => {
let xhr = new XMLHttpRequest(); // xml对象
xhr.open("GET", url, true); // 建立http请求
xhr.responseType = "json"; // 请求头信息
xhr.setRequestHeader("Accept", "application/json");
xhr.send(); // 发送请求
xhr.onreadystatechange = function () {
if (this.readyState !== 4) return;
if (this.status === 200) {
reslove(this.response);
} else {
reject(new Error(this.statusText));
}
};
});
return promise;
}
原生ajax
ajax的本质
前端和服务器端的中间层(ajax引擎),前端将数据数据处理、校验放到ajax中处理 前端将请求交给ajax,ajax将请求发送到服务器端,服务器端进行处理,将返回结果交给ajax,最后通过js将结果显示页面
不需要刷新整个界面就可以对网页的某个部分进行更新 异步提交,不需要等待服务器端的响应,就可以发起第二次请求
get请求
实现get请求
利用http创建一个服务器端
const http = require("http");
const hostname = "127.0.0.1";
const port = 3000;
const server = http.createServer((req, res) => {
res.end("Hello, World!\n");
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
创建一个前端简单demo
// html核心代码
<body>
<h1>通过原生ajax获取数据</h1>
<button id="btn1">点我获取数据</button>
<h4>展示数据</h4>
<div id="div1" class="div1"></div>
</body>
</html>
建立ajax请求
<script>
// 获取元素
let btn = document.getElementById("btn1");
// 监听鼠标的点击事件
btn.addEventListener('click', function () {
//创建一个ajax对象
let xhr = new XMLHttpRequest();
// 设置请求方法、url、是否异步
xhr.open("get", "http://localhost:3000/", true);
// 发送请求
xhr.send();
xhr.onreadystatechange = function () {
// 获取xhr的所有数据
console.log(xhr);
//请求已经完成,响应已经就绪
if (xhr.readyState === 4 && xhr.status === 200) {
// 获取响应的数据
console.log(xhr.responseText);
// 获取的响应数据展示在界面中
let div1 = document.getElementById("div1");
div1.innerHTML = xhr.responseText;
}
}
})
</script>
console.log(xhr);的结果
出现跨域
出现跨域,因为我的前端端口运行在5503端口,后端运行在3000,必然后出现跨域 解决方法:在服务器端设置允许的域
const server = http.createServer((req, res) => {
//允许所有跨域
// res.setHeader("Access-Control-Allow-Origin","*")
// 允许指定域 我的前端项目的端口是5503
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5503")
res.end("Hello, World!\n");
});
完成get请求
get实现一个ajax的步骤
//创建一个ajax对象
let xhr = new XMLHttpRequest();
// 设置请求方法、url、是否异步
xhr.open("get", "http://localhost:3000/", true);
// 发送请求
xhr.send();
//处理基于响应的事件 onreadystatechange
xhr.onreadystatechange = function () {
//请求已经完成,响应已经就绪 判断状态
if (xhr.readyState === 4 && xhr.status === 200) {
// todo
}
}
思考💡:readyState和status的区别
readyState和statu都是xhr的属性 readyState记录的是xhr运行时的状态,共有5个值,0~4 status记录的是http的状态码
如果只判断1个属性可以吗?
如果只判断readyState,服务器端是响应成功了,但是如果服务器端响应是存在错误的,那界面会出现不可预估的错误 如果只判断status,会出现弹窗3次的情况,分别对应的是readyState状态变化引起的,所以也不可以
post请求
原生ajax实现post请求
前端设置post请求代码,前端输入2个数,后端求和
// html核心代码
<label>请输入数字1:</label>
<input type="number" id="num1">
<br>
<label>请输入数字2:</label>
<input type="number" id="num2">
<br>
<button id="btn1">点我获取数据</button>
<h4>展示数据</h4>
<div id="div1" class="div1"></div>
// js核心代码
<script>
// 获取元素
let btn = document.getElementById("btn1");
// 监听鼠标的点击事件
btn.addEventListener('click', function () {
//创建一个ajax对象
let xhr = new XMLHttpRequest();
// 设置请求方法、url、是否异步
xhr.open("post", "http://localhost:3000/", true);
// 发送数据
let postStr = document.getElementById("num1").value + ","+ document.getElementById("num2").value;
//发送请求
xhr.send(postStr);
xhr.onreadystatechange = function () {
// 获取xhr的所有数据
console.log(xhr);
//请求已经完成,响应已经就绪
if (xhr.readyState === 4 && xhr.status === 200) {
// 获取响应的数据
console.log(xhr.responseText);
// 获取的响应数据展示在界面中
let div1 = document.getElementById("div1");
div1.innerHTML = xhr.responseText;
}
}
})
</script>
实现效果:
后端server分析
const http = require("http");
const hostname = "127.0.0.1";
const port = 3000;
const server = http.createServer();
// 绑定请求事件
server.on("request", (req, res) => {
let postData = '';
// req.on 接受客户端的数据
req.on('data', (chunk) => {
postData += chunk;
});
// end事件,获取的数据在end中处理
req.on('end', () => {
// 设置跨域
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5503")
let arr = postData.split(',');
let sum = Number(arr[0]) + Number(arr[1]);
// 操作返回值必须是string
res.write(JSON.stringify(sum));
res.end("结束");
})
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
post请求传入的数据要通过server.on 来监听;要在req.on 中获取数据,在req.on('end',)做数据的处理操作,并且可以通过res.end()返回数据,且返回的数据必须是string 格式