目录
前文:我会先讲一些要点,后面附带源码【记得启动服务】
<style>
#result {
width: 200px;
height: 100px;
border: solid 1px #90b;
}
</style>
1、GET请求
********************************** ajax *********************************
responseText、response:获取服务器端响应到客户端的数据 【app.get 中的 response.send('HELLO AJAX'); 的 HELLO AJAX】
console.log(xhr.status); // 状态码 【200等】 console.log(xhr.statusText); // 状态字符串 【ok】 console.log(xhr.getAllResponseHeaders()); // 所有响应头 // content-length: 10 // content-type: text/html; charset=utf-8 console.log(xhr.responseText); // HELLO AJAX console.log(xhr.response); // 响应体 // HELLO AJAX
********************************** js路由 *********************************
// request : 是对 请求报文的封装
// response :是对 响应报文的封装
response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应 设置允许跨域
response.send('HELLO AJAX'); // 回应请求,返回页面的信息
// send方法:只能发送字符串和buffer
(1)ajax
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
// 获取button元素
const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById("result");
//绑定事件
btn.onclick = function() {
//1. 创建对象 XMLHttpRequest 对象用于在后台与服务器交换数据
const xhr = new XMLHttpRequest();
//2. 初始化 设置请求方法和 url
// 1)请求方式 2)请求地址
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
// 如需将请求发送到服务器,我们使用 XMLHttpRequest对象的 open()和 send()方法:
//3. 发送
xhr.send();
//4. 事件绑定 处理服务端返回的结果
// on when 当....时候
// readystate 是 xhr 对象中的属性, 表示状态 0(未初始化) 1(表示open方法调用完 毕) 2(表示send方法调用完毕) 3(服务端返回的部分结果) 4(服务端返回的所有结果)
// change 改变
xhr.onreadystatechange = function() {
//判断 (4就是服务端返回了所有的结果)
if (xhr.readyState === 4) {
//判断响应状态码(status) 200 404 403 401 500
// 2xx (2开头的)成功
if (xhr.status >= 200 && xhr.status < 300) {
//处理结果 行 头 空行 体 // 响应
console.log(xhr.status); // 状态码 【200等】
console.log(xhr.statusText); // 状态字符串 【ok】
console.log(xhr.getAllResponseHeaders()); // 所有响应头
// content-length: 10
// content-type: text/html; charset=utf-8
// *** responseText、response:获取服务器端响应到客户端的数据 【app.get 中的 response.send('HELLO AJAX'); 的 HELLO AJAX
console.log(xhr.responseText); // HELLO AJAX
console.log(xhr.response); // 响应体 // HELLO AJAX
//设置 result 的文本
result.innerHTML = xhr.response;
} else {
}
}
}
}
</script>
</body>
(2)js路由
app.get('/server', (request, response) => {
// 设置响应 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 用浏览器http://127.0.0.1:8000/server 响应 send里面的内容
response.send('HELLO AJAX');
});
2、POST请求
********************************** ajax *********************************
- GET请求 -- 参数写在open的url路径的最后面
- POST请求 -- 参数写在send中
- POST设置请求头:
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 固定 xhr.setRequestHeader('name', 'atguigu'); 自定义【需要在server.js把post改成all,添加response.setHeader('Access-Control-Allow-Headers', '*');】
(1)ajax
<body>
<div id="result"></div>
<script>
const result = document.getElementById("result");
//绑定事件
result.addEventListener("mouseover", function() {
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化 设置类型与 URL
xhr.open('POST', 'http://127.0.0.1:8000/server');
// * 设置请求头(post请求必须要设置)
// 预定义请求头 固定写法
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 自定义请求头
xhr.setRequestHeader('name', 'atguigu');
//3. 发送 【send里面的参数的格式 如下】
xhr.send('a=100&b=200&c=300');
// xhr.send('a:100&b:200&c:300');
// xhr.send('1233211234567');
//4. 事件绑定
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
}
});
</script>
</body>
(2)js路由
// all:可以接受任意类型的请求
app.all('/server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头 允许所有自定义响应头
response.setHeader('Access-Control-Allow-Headers', '*');
// 用浏览器http://127.0.0.1:8000/server 响应 send里面的内容
response.send('HELLO AJAX post');
});
3、服务端响应JOSN数据
********************************** js路由 *********************************
由于服务端send只能发送字符串和buffer【其他形式强行转换为字符串发送】
但是并不是我们需要得到的 对象格式
例:后台传一个 对象 ,那么页面显示的是下面的形式【字符串】
JSON.stringify()方法:将一个 JS对象或值转换为 JSON 字符串
********************************** ajax *********************************
1、手动对数据转化 (在ajax将从服务器得来的 字符串 -> 对象 )
JSON.parse()方法:将JSON格式字符串转换为JS对象
2、 自动转换 (借助xhr对象上面的一个属性responseType来设置)
xhr.responseType = 'json'; // 设置响应体数据的类型都为JSON
设置后,在状态码事件绑定中,就不需要对传进来的 字符串 -> 对象
(1)ajax
<body>
<div id="result"></div>
<script>
const result = document.getElementById('result');
// 绑定任意键盘按下事件
window.onkeydown = function() {
//发送请求
const xhr = new XMLHttpRequest();
//设置响应体数据的类型 (设置自动转换 接着下面的 2)
xhr.responseType = 'json';
//初始化
xhr.open('GET', 'http://127.0.0.1:8000/json-server');
//发送
xhr.send();
//事件绑定
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(typeof(xhr.response),xhr.response);
result.innerHTML = xhr.response;// {name: '广石油'}
// 1. 手动对数据转化 (从服务器得来的字符串再转换为对象)
// let data = JSON.parse(xhr.response);
// console.log(typeof(data),data);
// result.innerHTML = data.name;
// 2. 自动转换 【接着上面的 responseType】
// console.log(typeof(xhr.response),xhr.response);
// result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
(2)js路由
app.all('/json-server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头
response.setHeader('Access-Control-Allow-Headers', '*');
// 响应一个数据
const data = {
name: '广石油'
};
// 对 对象 进行 字符串 转换
let str = JSON.stringify(data);
// 用浏览器http://127.0.0.1:8000/json-server 响应 send里面的内容
response.send(str);
});
4、IE缓存问题
********************************** ajax *********************************
在xhr.open里面的路径加 ?t=' + Date.now() 或者 ?t=' + Math.random(),就是每次click 就会更新一个时间戳,解决服务端改变返回的数据后,IE页面数据显示不变问题
(1)ajax
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
const btn = document.getElementsByTagName('button')[0];
const result = document.querySelector('#result');
btn.addEventListener('click', function() {
const xhr = new XMLHttpRequest();
// 在xhr.open里面的路径加 ?t=' + Date.now() 或者 ?t=' + Math.random(),就是 每次click 就会更新一个时间戳
xhr.open("GET", 'http://127.0.0.1:8000/ie?t=' + Date.now());
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
}
})
</script>
</body>
(2)js路由
// 针对IE缓存
app.get('/ie', (request, response) => {
// 设置响应 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 用浏览器http://127.0.0.1:8000/ie 响应 send里面的内容
response.send('HELLO IE');
});
5、AJAX请求超时与网络异常
在服务端server.js上开启一个为3s的定时器,时间到了后,才send返回。
********************************** ajax *********************************
xhr.timeout = 2000; | 超时设置 2s 设置【2秒没有结果,把请求做一个取消】 |
xhr.ontimeout = function() { alert("网络异常"); } | 超时回调 取消请求后,做一个回调提示 |
xhr.onerror = function() { alert("网路故障!"); } | 网络异常回调,断网时提示 |
(1)ajax
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
// 网络超时设置,点击按钮,2秒没有反应,提示用户,超时
const btn = document.getElementsByTagName('button')[0];
const result = document.querySelector('#result');
btn.addEventListener('click', function() {
const xhr = new XMLHttpRequest();
// 1、超时设置 2s 设置【2秒没有结果,把请求做一个取消】
xhr.timeout = 2000;
// 2、超时回调 取消请求后,做一个回调提示
xhr.ontimeout = function() {
alert("网络异常, 请稍后重试!!");
}
// 3、网络异常回调,断网时提示
xhr.onerror = function() {
alert("你的网络似乎出了一些问题!");
}
xhr.open("GET", 'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
}
})
</script>
</body>
(2)js路由
// 延时响应
app.get('/delay', (request, response) => {
// 设置响应 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 用浏览器http://127.0.0.1:8000/... 响应 send里面的内容
setTimeout(() => {
// 设置响应体
response.send('延时响应');
}, 3000);
});
6、AJAX取消请求
在服务端server.js上开启一个为3s的定时器,时间到了后,才send返回。
********************************** ajax *********************************
发送请求未到3s,这个时候需要终止ajax请求,我们需要调用xhr对象上的abort方法 : 终止AJAX 请求 xhr.abort();
(1)ajax
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
//获取元素对象
const btns = document.querySelectorAll('button');
let xhr = null;
btns[0].onclick = function() {
xhr = new XMLHttpRequest();
xhr.open("GET", 'http://127.0.0.1:8000/delay');
xhr.send();
}
// **************************************
// ** xhr对象上的abort : 终止AJAX 请求 **
// **************************************
btns[1].onclick = function() {
xhr.abort();
}
</script>
</body>
(2)js路由(同上delay)
7、重复请求问题
在服务端server.js上开启一个为3s的定时器,时间到了后,才send返回。
********************************** ajax *********************************
- 用户在发送请求时,重复发送会导致效率变低,我们取最新的请求继续发送,取消之前的请求
- 使用外部变量isSending = false,用户点击发送请求isSending = true;,当请求状态未全部返回(状态4),用户再次点击就取消if (isSending) x.abort(); ,状态全部返回后,相当于已经完成一次请求isSending = false;,再次请求就是第一次请求了。
(1)ajax
<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://127.0.0.1:8000/delay');
x.send();
x.onreadystatechange = function() {
if (x.readyState === 4) {
// 修改标识变量【不需要加状态码判断,因为可能会请求失败,那么就不会执行 下面的代码】
isSending = false;
}
}
}
</script>
</body>