总而言之:ajax不是什么新鲜的对象,我们把它当作是在一个已有的网页中,我们可以通过它请求后端的数据来显示在之前的网页中。
btn.onclick = function(){
//1. 创建对象
const xhr = new XMLHttpRequest();//浏览器开发者选项中的xhr里面的信息就是该页面的ajax请求
//2. 初始化 设置请求方法和 url
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
//3. 发送
xhr.send();
//4. 事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function(){
//判断 (服务端返回了所有的结果)
if(xhr.readyState === 4){
// 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 的文本
result.innerHTML = xhr.response;
}else{
}
}
}
}
result.addEventListener("mouseover", function(){
//1. 创建对象
const xhr = new XMLHttpRequest();
xhr.responseType='json'
//2. 初始化 设置类型与 URL
xhr.open('POST', 'http://127.0.0.1:8000/server');//有时候ie浏览器会有缓存问题,因此通常情况下最好给每个url拼接上一个时间戳参数
//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','xxx');//自定义的请求头需要在后端中设置Access-Control-Allow-Headers响应头
//3. 发送
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;
}
}
}
});
btn.addEventListener('click', function(){
const xhr = new XMLHttpRequest();
//超时设置 2s 设置
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function(){
alert("网络异常, 请稍后重试!!");
}
//网络异常回调
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>
//获取元素对象
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;
}
}
}
// abort
btns[1].onclick = function(){
x.abort();
}
</script>
//1. 引入express
const express = require('express');
//2. 创建应用对象
const app = express();
//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
//all方法表示所有类型的请求都可以,get、post、delete。。。
app.all('/server', (request, response)=>{
//设置响应
//response.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");//只对http://127.0.0.1:3000这个url的请求允许跨域
response.setHeader("Access-Control-Allow-Origin","*")//对所有请求允许跨域
response.setHeader("Access-Control-Allow-Headers","*")//允许各种请求头,包括自定义的和http已经定义的请求头
response.send('HELLO EXPRESS');
});
//4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000 端口监听中....");
});
xhr.readyState 可以用来查看请求当前的状态
同源策略
同源策略是浏览器的一种安全策略。所谓的同源是指:协议、域名】端口号必须完全相同,而违背同源策略就是跨域。
如果违背同源策略,浏览器的开发者工具就会报如下错误,该网页是从5500端口获取的,但是ajax的请求却是8000端口。
解决跨域问题有两种方式:
CORS
JSONP
JSONP(JSON with Padding),是一个非官方的跨域解决方案,只支持 get 请求。在网页有一些标签天生具有跨域能力,比如:img link iframe script。JSONP 就是利用 script 标签的跨域能力来发送请求的。
案例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例</title>
</head>
<body>
用户名: <input type="text" id="username">
<p></p>
<script>
//获取 input 元素
const input = document.querySelector('input');
const p = document.querySelector('p');
//声明 handle 函数
function handle(data){
input.style.border = "solid 1px #f00";
//修改 p 标签的提示文本
console.log(data)
p.innerHTML = data.name;
}
//绑定事件
input.onblur = function(){
//获取用户的输入值
let username = this.value;
//向服务器端发送请求 检测用户名是否存在
//1. 创建 script 标签
const script = document.createElement('script');
//2. 设置标签的 src 属性
script.src = 'http://127.0.0.1:8000/server';
//3. 将 script 插入到文档中
document.body.appendChild(script);
}
</script>
</body>
</html>
//1. 引入express
const express = require('express');
//2. 创建应用对象
const app = express();
//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.all('/server', (request, response)=>{
//设置响应
// response.setHeader("Access-Control-Allow-Origin","*")
// response.setHeader("Access-Control-Allow-Headers","*")
const data = {
name: 'sdsdsd'
};
response.end(`handle(${JSON.stringify(data)})`);//这样就会回调到html中的handle方法
});
//4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000 端口监听中....");
});
除了前面介绍的几个字ajax的请求之外,fetch函数也是可以用来进行ajax请求的
https://developer.mozilla.org/zh-CN/docs/Web/API/fetch