一、原生AJAX
1. AJAX简介
Asynchronous JavaScript And XML,即异步的JS和XML,通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
2. XML简介
XML可扩展标记语言,被设计用来传输和存储数据。
XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全部都是自定义标签,用来表示一些数据。
但是现在已经被JSON取代了
3. AJAX特点
AJAX优点:(1)可以无需刷新页面而与服务器端进行通信 (2)允许你根据用户事件来更新部分页面内容
AJAX缺点:(1)没有浏览历史,不能回退 (2)存在跨域问题(同源) (3)SEO不友好
4. HTTP协议
HTTP(hypertext transport protocol)协议,即超文本传输协议,详细规定了浏览器和万维网服务器之间互相通信的规则,主要包括请求、响应两块内容。
请求报文
响应报文
5. express的基本使用
6. Ajax请求的基本操作
<!-- 需求:点击后向服务端发送请求,然后把服务端返回的响应体结果呈现在div中 -->
<button>点击发送请求</button>
<div id="result"></div>
<script>
const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById('result');
btn.onclick = function () {
// AJAX操作步骤:
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化:设置请求的类型和url
xhr.open('GET', 'http://127.0.0.1:8000/server');
// 3.发送
xhr.send();
// 4.事件绑定:处理服务端返回的结果
// readyState是xhr对象中的属性,表示状态,有五个值0,1,2,3,4,0-未初始化,1-open方法调用完毕,2-send方法调用完毕,3-服务端返回部分结果,4-服务端返回所有结果
// onreadystatechange事件会触发4次,readyState改一次触发一次
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;
}
}
}
}
</script>
7. AJAX中如何传递参数?
在url后面缀参数
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
8. POST请求体的设置
请求体可以设置任意格式数据,只要服务端能处理
// xhr.send('a=100&b=200&c=300');
// xhr.send('a:100&b:200&c:300');
xhr.send('141325');
9. 请求头的设置
一般会把身份校验的信息放在头信息里面,把它传递给服务器,由服务器对参数做提取,对用户的身份做校验。
// 设置请求头信息
// 预定义请求头
// Content-Type用于设置请求体内容的类型,application/x-www-form-urlencoded就是参数查询字符串的类型(固定写法)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 自定义请求头
xhr.setRequestHeader('name', 'atguigu');
10. AJAX请求,服务端响应JSON数据
const result = document.getElementById('result');
window.onkeydown = function () {
// 发送请求
const xhr = new XMLHttpRequest();
// 设置响应体数据的类型
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(xhr.response);
// result.innerHTML = xhr.response;
// 方法1.手动对数据进行转换
// let data = JSON.parse(xhr.response);
// console.log(data);
// result.innerHTML = data.name;
// 方法2:自动转换(借助于xhr对象上的responseType属性)
console.log(xhr.response);
result.innerHTML = xhr.response.name;
}
}
}
}
11. nodemon工具
自动监测文件的变化,帮助我们自动重启服务
12. AJAX请求超时与网络异常处理
// 2s没有返回结果,提醒用户网络超时
const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById('result');
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 < 3000) {
result.innerHTML = xhr.response;
}
}
}
})
13. AJAX取消请求
借助于AJAX对象的abort()方法取消
<button>点击发送请求</button>
<button>点击取消</button>
<script>
const btns = document.querySelectorAll('button');
let x = null;
btns[0].onclick = function () {
x = new XMLHttpRequest();
x.open('GET', 'http://127.0.0.1:8000/delay');
x.send();
}
// abort方法取消请求
btns[1].onclick = function () {
x.abort();
}
</script>
14. AJAX重复发送请求问题
节流阀
<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();//已经创建出变量,就一定在发送AJAX请求
// 修改标识变量的值
isSending = true;
x.open('GET', 'http://127.0.0.1:8000/delay');
x.send();
x.onreadystatechange = function () {
if (x.readyState === 4) {
// 发送完毕,修改标识变量的值
isSending = false;
}
}
}
</script>
二、jQuery中的AJAX
1. get和post发送请求方法
<h2>jQuery发送AJAX请求</h2>
<button class="btn btn-primary">GET</button>
<button class="btn btn-danger">POST</button>
<button class="btn btn-info">通用型方法</button>
<script>
$('button').eq(0).click(function () {
// $.get发送GET请求
// 4个参数:给谁发、发送的参数、回调函数(函数的参数是响应体)、响应体的数据类型
$.get('http://127.0.0.1:8000/jquery-server', { a: 100, b: 200 }, function (data) {
// 参数data是响应体
console.log(data);
}, 'json')
})
$('button').eq(1).click(function () {
// $.post发送POST请求
$.post('http://127.0.0.1:8000/jquery-server', { a: 100, b: 200 }, function (data) {
// 参数data是响应体
console.log(data);
})
})
</script>
2. 通用-ajax方法发送请求
$('button').eq(2).click(function () {
// 接受一个参数对象,包含几个属性:url给谁发、发送的参数、请求的类型、成功的回调
$.ajax({
// url给谁发
url: 'http://127.0.0.1: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: 'abcd',
d: 400
}
})
});
三、axios
一个AJAX工具库
1. get和post发送请求方法
数据的返回和处理方式与jQuery不同,jQuery采用回调函数,axios基于Promise,用then()方法
// 设置baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[0].onclick = function () {
// GET请求
// 参数:URL、其他配置
axios.get('/axios-server', {
// url参数
params: {
id: 100,
vip: 7
},
// 请求头信息
headers: {
name: 'wsq',
age: 24
}
}).then(value => {
console.log(value);
})
}
btns[1].onclick = function () {
// POST请求
// 参数:URL、请求体、其他配置
axios.post('/axios-server',
// 请求体
{
username: 'admin',
password: '123456789qqq'
}, {
// url参数
params: {
id: 200,
vip: 9
},
// 请求头信息
headers: {
height: 180,
weight: 180
},
})
}
2. 通用-ajax方法发送请求(函数)
btns[2].onclick = function () {
axios({
// 请求方法
method: 'POST',
// url(给谁发)
url: '/axios-server',
// url参数
params: {
vip: 99,
level: 31
},
// 头信息
headers: {
a: 100,
b: 200
},
// 请求体参数
data: {
username: 'admin',
password: 'afagagasgaa'
}
}).then(response => {
// 响应里的所有内容
console.log(response);
// 响应状态码
console.log(response.status);
// 响应状态字符串
console.log(response.statusText);
// 响应头信息
console.log(response.headers);
// 响应体
console.log(response.data);
})
}
四、使用 fetch 函数发送AJAX请求
const btn = document.querySelector('button');
btn.onclick = function () {
fetch('http://127.0.0.1:8000/fetch-server?vip=99', {
// 请求方法
method: 'POST',
// 请求头
headers: {
name: 'wsq'
},
// 请求体
body: 'username=admin&password=asageaegaegea'
}).then(response => {
console.log(response);
// 不能直接获取响应体,要借助text方法,如果返回的是json,改用json方法,就能解析成js对象
// text方法、json方法均能返回一个Promise对象。
// return response.text();
return response.json();
}).then(response => {
// 响应体
console.log(response);
})
}
五、跨域
1. 同源策略
同源策略(Same-Origin Policy)最早由Netscape公司提出,是浏览器的一种安全策略。
同源:协议、域名、端口号必须完全相同。
违背同源策略就是跨域。
网页资源本身来自于某个服务器,在发送请求时如果依然向这个服务器发送,就是满足同源策略的,此时目标请求的资源和网页资源都是来自于该服务器。
AJAX在发送请求时,默认要遵循同源策略。
2. 如何解决跨域
2.1 JSONP
JSONP(JSON with Padding)是一个非官方的跨域解决方案,纯粹凭借程序员开发出来,只支持get请求。
JSONP怎么工作?
在网页有一些标签天生具有跨域能力,比如:img、link、iframe、script
JSONP就是利用script标签的跨域能力来发送请求的。
JSONP的使用
用户名: <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 = "1px solid #f00";
// 修改p标签的提示文本
p.innerHTML = data.msg;
}
input.onblur = function () {
// 获取用户的输入值
let username = this.value;
// 向服务端发送请求,检测用户名是否存在
// 1.创建一个script标签
const script = document.createElement('script');
// 2.设置标签的src属性
script.src = 'http://127.0.0.1:8000/check-username';
// 3.将script插入到文档中
document.body.appendChild(script);
}
</script>
jQuery-jsonp
<button>点击发送jsonp请求</button>
<div id="result"></div>
<script>
// 需求:点击按钮,向8000端口发送请求,返回结果呈现在div中
$('button').eq(0).click(function () {
// 用jquery发送jsonp请求时,url最后需要补一个参数callback=?(固定写法),而callback就是getJSON的第二个参数
$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function (data) {
$('#result').html(`
名称:${data.name},<br/>
校区:${data.city}
`);
})
});
</script>
2.2 CORS
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段(响应头),允许服务器声明哪些源站通过浏览器有权访问哪些资源。
CORS怎么工作的?
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
跨源资源共享(CORS) - HTTP | MDN跨源资源共享 (CORS)(或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS使用CORS设置跨域:加上响应头就可以跨域
app.all('/cors-server', (request, response) => {
// 设置响应头,*表示通配,跨域请求允许所有网页,也可以指定网页
response.setHeader('Access-Control-Allow-Origin', '*');
// response.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500');
// 允许客户端在发送请求时,发送任意的请求头,可以是预定义的,也可以是自定义的
response.setHeader('Access-Control-Allow-Headers', '*');
// 表示请求方法可以是任意的,GET,POST,PUT,DELETE,PATCH等等方法都可以使用
response.setHeader('Access-Control-Allow-Methods', '*');
response.send('Hello CORS');
})