共计 6006 个字符,预计需要花费 16 分钟才能阅读完成。
教程链接
Ajax 介绍:
Asynchronous JavaScript and xml
在页面不刷新的状况下向服务器发送申请,实现数据的替换,用户体验更好
懒加载,按需加载——> 资源利用率进步,整体页面加载速度变快(首屏加载)
XML Vs. JSON
XML
设计被用来传输和存储数据。
HTML 用来在网页当中出现数据。
HTML 都是预约义标签,XML 中没有预约义标签,都是自定义标签。
最开始 Ajax 在进行数据交换的时候应用的格局就是 XML(服务器端返回给客户端的就是 XML 格局的字符串)
JSON
JSON 更简洁,传输的体积更小,数据转换也更加容易,能够间接借助 JSON API 的一些办法,疾速将字符串转成 JS 对象
Ajax 的优缺点:
长处
- 无需刷新页面就能够服务器发送申请
- 容许依据用户事件向服务端发送申请,对页面部分刷新
毛病
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO(Search Engine Optimization)不敌对:爬虫爬不到
HTTP
Hypertext Transport protocol(超文本传输协定),协定具体规定了浏览器和服务器之间相互通信的规定
申请报文
重点是格局与参数
行 POST /?ie=utf-8 HTTP/1.1 申请类型、门路、协定版本
头 Host: aiguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-ulrencoded 申请体内容的类型
User-Agent: chrome 83
空行
体 username=admin&password=admin GET 申请的申请体为空
GET – Query String parammeters 申请参数的解析显示
Form Data/request payload
响应报文
行 HTTP/1.1 200 OK 协定版本、响应状态码、状态字符串
头 Content-Type:text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip
对响应体内容做相干形容:类型、长度、压缩形式
空行
体 次要返回的后果
<html>
<head></head>
<body>
<h1> 尚硅谷 ></h1>
</body>
</html>
404- 找不到 Not Found
403- 没有权限
401- 未受权
303-See Other
500- 外部谬误
200- 申请胜利
Node.js
一个应用程序,能够解析 JS 代码,通过 JS 代码能够对计算机资源进行操作
Express 的根本应用
## 装置
npm i express
// 应用
// 1. 引入 express
const express = require('express');
// 2. 创立利用对象
const app = express();
// 3. 创立路由规定
// request 是对申请报文的封装
// response 是对响应报文的封装
app.get('/', (request, response) => {
// 设置响应
response.send('Hello Express');
})
// 4. 监听端口并启动服务
app.listen(8000, () => {console.log('服务已启动,8000 端口监听中...');
})
根本的 Ajax 操作
// 创建对象
const xhr = new XMLHttpRequest();
// 初始化 设置申请办法和 url
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
// 发送申请
xhr.send();
// 事件绑定 解决服务端返回的后果
// stateready 0- 初始化 1-open 2-send 3- 服务端返回局部后果 4- 服务端返回所有后果
xhr.onstatereadychange = function () {
// 判断 服务端返回全副的后果
if (xhr.stateReady === 4) {
// 判断 响应状态码 200 404 403 401 500
// 胜利 2xx
if (xhr.status >= 200 && xhr.status < 300) {
// 解决胜利的后果
console.log(xhr.status); // 响应状态码
console.log(xhr.statusText); // 状态字符串
console.log(xhr.getAllResponseHeaders()); // 所有响应头
console.log(xhr.response); // 响应体
}
}
}
发送 post 申请
// 初始化 设置申请类型和 url
xhr.post('POST', 'http://127.0.0.1:8000/server');
// 设置申请体并发送申请
xhr.send('a=100&b=200&c=300');
设置申请头
xhr.setHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setHeader('name', 'atguigu'); // 不是预约义的申请头,是自定义的,会有平安机制限度,服务端须要做头部解决,容许携带的头部字段 response.setHeader('Access-Control-Allow-Headers', '*');
解决服务端返回的 json 数据
// 服务端返回
response.send({name: 'atguigu'});
// 客户端接管
// 1. 手动转换
const data = JSON.parse(xhr.response); // 失去 json 数据
// 2. 主动转换:设置 responseType
xhr.responseType = 'json';
// ...
const data = xhr.response;
解决超时和网络异样
// 设置超时 2s 超时
xhr.timeout = 2000;
// 网络超时后的回调
xhr.ontimeout = function () {alert('网络异样,请从新刷新!!');}
// 网络异样的回调
xhr.onerror = function () {alert('您的网络仿佛有一些问题!');}
申请勾销
xhr.abort();
反复申请:场景——间断屡次点击按钮发送申请
let isSending = false; // 标识变量 是否正在发送 Ajax 申请
if(isSending) xhr.abort(); // 如果正在发送申请,则勾销正在发送的申请,从新创立一个新的申请
xhr = new XMLHttpRequest();
isSending = true; // 批改 标识变量的值
xhr.open('method', 'url');
xhr.send();
xhr.onreadystatechange = function () {if(xhr.readyState === 4) {isSending = false; // 重置 标识变量}
}
jQuery 发送申请
// get 申请, 第四个参数是响应体后果类型
$.get('url', {a: 100, b: 200}, function(data) {console.log(data);
}, 'json');
// post 申请
$.post('url', {a: 100, b: 200}, function(data) {console.log(data);
});
// 通用型办法 ajax, 满足个性化需要
$.ajax({
// url
url: '',
method: '',
// get 申请的 url 参数,post 申请的申请体参数
data: {
a: 100,
b: 200
},
// 响应体后果的类型
dataType: 'json',
// 胜利的回调
success: function(data) {console.log(data);
},
// 超时工夫
timeout: 2000,
// 失败的回调(包含超时)error: function() {console.log('出错啦!');
},
// 头信息
headers: {
name: 'xxx',
token: '123'
}
});
Axios 发送 ajax 申请
// 设置 baseURL
axios.defauts.baseURL = 'http://127.0.0.1:8000';
axios.get('/axios-server', {
// url 参数
params: {
name: 'tom',
age: 18
},
// 头信息参数
headers: {
username: 'hh',
token: '123'
}
}).then(value => {console.log(value);
})
axios.post('/axios-server', {
// 申请体参数
password: 'admin',
username: 'admin'
}, {
params: {
name: 'jack',
age: 19
},
headers: {
username: 'hh',
token: '123'
}
});
// 通用型办法
axios({
url: '/axios-server',
method: 'POST',
// url 参数
params: {
name: 'green',
age: 20
},
headers: {
username: 'hh',
token: '123'
},
// 申请体参数
data: {
password: 'admin1',
username: 'admin1'
}
}).then(response => {console.log(response.status); // 响应状态码
console.log(response.statusText); // 响应状态码字符串
console.log(response.headers); // 响应头信息
console.log(response.data); // 响应体
})
fetch 发送申请
fetch('http://127.0.0.1:8000/fetch-server', {
method: 'POST',
headers: {token: '123'},
body: 'a=100&b=200'
}).then(response => {// return response.text(); // 响应体解析为一般文本
return response.json(); // 响应体解析为 json}).then(data => {console.log(data); // 响应体
});
申请体
原生 ajax 申请:默认 request payload
jQuery:默认 form data
axios:默认 request payload
fetch:默认 request payload
同源策略
协定、域名、端口号完全一致
解决跨域的计划:
1. JSONP(JSON with Padding)
只反对 get 申请。利用 script 标签可获取跨域资源的特点,可跨域的标签还有 img、link、iframe、script 等。
服务端响应的是 js 代码,返回函数调用,并把参数传递进去。浏览器对代码进行解析并执行,函数申明由前端本人定义。
// node 局部
app.get('/jsonp-server', (request, response) => {
const data = {name: 'atguigu'}
const str = JSON.stringfy(data);
response.end(`handle(${str})`);
});
<!-- 前端局部 -->
<script>
function handle(data) {const btn = document.getElementById('result');
btn.innerHTML = data.name;
}
</script>
<script src="http://127.0.0.1:8000/jsonp-server"></script>
实际
// 前端局部
const input = document.querySelector('input');
const p = document.querySelector('p');
function handle(data) {
p.innerHTML = data.msg;
input.style.border = 'solid 1px #f00';
}
input.onblur = function () {const script = document.createElement('script');
script.src = 'http://127.0.0.1:8000/check-username';
document.body.appendChild(script);
}
// node 局部
app.all('/check-username', (request, response) => {
const data = {
error: 1,
msg: '用户名已存在'
};
const str = JSON.stringify(data);
response.end(`handle(${str})`);
});
jQuery 中应用 JSONP
// node 局部
app.get('/jquey-jsonp-server', (request, response) => {
const data = {
name: 'atguigu',
city: ['北京', '上海', '深圳']
}
const str = JSON.stringfy(data);
const cb = request.query.callback;
response.end(`${cb}(${str})`);
});
// ?callback=? 是固定写法,jQuery 会随机生成一个回调函数名称,服务端能够调用这个函数,相当于调用 getJSON 的第二个参数(函数)$.getJSON('http://127.0.0.1:8000/jquey-jsonp-server?callback=?', function (data) {$('#result').html(`
名字:${data.name},
校区:${data.city}
`);
})
2. CORS(Cross-Origin Resource Sharing)
跨域资源共享
新增了一组 HTTP 首部字段(header)来解决跨域问题,容许服务器申明哪些源站通过浏览器有权限拜访哪些资源
response.setHeader('Access-Control-Allow-Origin', '*'); // 容许的申请起源
response.setHeader('Access-Control-Allow-Headers', '*'); // 容许携带的头信息,用于预检申请的响应
response.setHeader('Access-Control-Allow-Methods', '*'); // 容许的申请类型,用于预检申请的响应
response.setHeader('Access-Control-Expose-Headers', 'token'); // 容许浏览器能够拿到的自定义响应头
具体可设置的 CORS 头信息能够参考 MDN