一、 AJAX 和 Fetch 对比
1.1 AJAX 概述
AJAX 是最早出现请求数据的方式,它不需要不需要刷新整个页面即可更新部分数据。
属于原生 JS 范畴 ,技术核心是 XMLHttpRequest 对象。
AJAX 请求过程:创建 XMLHttpRequest 对象、连接服务器、发送请求、接收响应数据
一般使用之前,我们都需要把它们封装使用,如下:
const ajax = function() {
// 创建xhr对象
// 判断浏览器是否支持XMLHttpRequest
let xhr;
if (window.XMLHttpRequest) {
// 高级浏览器
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// IE低版本
xhr = new ActiveXObject();
} else {
alert('你的浏览器不支持ajax')
}
// get 请求
this.get = function(url,param) {
// param 为原始数据类型
// get请求没有请求体,因此常常将数据放在地址上,作为请求头的一部分(query数据)
xhr.open('get',url + '?param=' + param,true) // 第三个参数异步与否
// 监听数据返回
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
fn(xhr.responseText)
}
}
xhr.send()
}
// post 请求
this.post = function(url, data) {
// post请求既有请求头,也有请求体,所以可以添加query数据,也可以添加data数据
xhr.open('post', url, true)
xhr.setRequestHeader('Content-type','application/json') // 决定传数据格式
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
fn(xhr.responseText)
}
}
xhr.send(JSON.stringify(data))
}
}
封装完成,开始使用的时候你会发现,body 和 header 处理得有些乱,还有回调地狱的问题,所以我们出现了新的 fetch 请求技术。
1.2 Fetch 概述
fetch 可以解决回调地狱的问题。,它用于发起获取资源的请求。返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。
语法:
Fetch(url, options)
options 一个配置项对象,包括所有对请求的设置。可选的参数有:
- method: 请求使用的方法,如 GET、POST、PUT、DELETE。
- headers: 请求的头信息,形式为 Headers 的对象或包含 ByteString 值的对象字面量。
- body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
- mode: 请求的模式,如 cors、no-cors 或者 same-origin。
- credentials: 请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie,必须提供这个选项,从 Chrome 50 开始,这个属性也可以接受 FederatedCredential (en-US) 实例或是一个 PasswordCredential (en-US) 实例。
- cache: 请求的 cache 模式:default、 no-store、 reload 、 no-cache、 force-cache 或者 only-if-cached。
- redirect: 可用的 redirect 模式:follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误),或者 manual (手动处理重定向)。在 Chrome 中默认使用 follow(Chrome 47 之前的默认值是 manual)。
- referrer: 一个 USVString 可以是 no-referrer、client 或一个 URL。默认是 client。
- referrerPolicy: 指定了 HTTP 头部 referer 字段的值。可能为以下值之一:no-referrer、 no-referrer-when-downgrade、origin、origin-when-cross-origin、 unsafe-url。
- integrity: 包括请求的 subresource integrity 值(例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。
Fetch 优点主要有:·
- 语法简洁,更加语义化
- 基于标准 Promise 实现,支持 async/await
- 同构方便,使用 isomorphic-fetch
var myInit = { method: 'GET',
headers: {
'Content-Type': 'image/jpeg'
},
mode: 'cors',
cache: 'default' };
var myRequest = new Request('flowers.jpg', myInit);
注:fetch 属于比较新的技术,低版本浏览器和IE浏览器支持性不好。
Fetch 代码封装:
const $http = async (url = '', data = {}, type = 'GET') => {
const baseUrl = "" // 基础路径
type = type.toUpperCase(); // 请求方式小写转换成大写
url = baseUrl + url; // 请求地址的拼接
let token = ''
if(sessionStorage.getItem('token')) {
token = sessionStorage.getItem('token')
}
if (type == 'GET') {
let dataStr = ''; //数据拼接字符串
Object.keys(data).forEach(key => {
dataStr += key + '=' + data[key] + '&';
})
if (dataStr !== '') {
dataStr = dataStr.slice(0, dataStr.lastIndexOf('&'));
url = url + '?' + dataStr;
}
}
let requestConfig = {
credentials: 'same-origin',
method: type,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
// 获取 token
'Authorization': token
},
mode: "cors", // 用来决定是否允许跨域请求 值有 三个 same-origin,no-cors(默认)以及 cores;
cache: "force-cache" // 是否缓存请求资源 可选值有 default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
}
if (type == 'POST') {
Object.defineProperty(requestConfig, 'body', {
value: JSON.stringify(data)
})
}
try {
const response = await fetch(url, requestConfig);
const responseJson = await response.json();
return responseJson
} catch (error) {
throw new Error(error)
}
}
附录一:AJAX 优缺点及使用场景
1. AJAX 的优点
- 无刷新更新数据:在不刷新整个页面的情况下维持与服务器通信
- 异步与服务器通信:使用异步的方式与服务器通信,不打断用户的操作
- 前端与后端负载均衡:将一些后端的工作移到前端,减少服务器与带宽的负担
- 基于规范被广泛支持:不需要下载浏览器插件或者小程序,但需要客户允许JavaScript在浏览器上执行。
- 界面与应用分离:Ajax使得界面与应用分离,也就是数据与呈现分离
2. AJAX 的缺点
- Ajax不支持Back与History功能,即对浏览器机制的破坏:在动态更新页面的情况下,用户无法回到前一页的页面状态,因为浏览器仅能记忆历史纪录中的静态页面
- 安全问题:AJAX技术给用户带来很好的用户体验的同时也对IT企业带来了新的安全威胁,Ajax技术就如同对企业数据建立了一个直接通道。这使得开发者在不经意间会暴露比以前更多的数据和服务器逻辑。ajax的逻辑可以对客户端的安全扫描技术隐藏起来,允许黑客从远端服务器上建立新的攻击。还有ajax也难以避免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于credentials的安全漏洞等。
- 对搜索引擎支持较弱:如果使用不当,AJAX会增大网络数据的流量,从而降低整个系统的性能。解决的办法:可以先用服务器渲染。
- 破坏程序的异常处理机制
- 违背URL与资源定位的初衷
- 不能很好地支持移动设备
- 客户端肥大,太多客户段代码造成开发上的成本
3. 应用场景
- 动态加载数据,按需取得数据。(树形菜单,联动菜单…)
- 改善用户体验。(输入前提示。带进度条文件上传)
- 电子商务应用。(购物车,邮件订阅)
- 访问第三方服务。(访问搜索服务,rss阅读器)