00、Web API
01、服务器API(AJAX )
AJAX(Asynchronous JavaScript And XML),就是异步调用JavaScript 与服务器通信,实现动态网页编程的技术总称。是一系列技术的合集,涉及HTML/XHTML、CSS、 JavaScript、DOM、XML、XSLT,以及最重要的 XMLHttpRequest。最重要的特征和作用就是实现页面局部更新。
实现AJAX的几个主流技术:
- XMLHttpRequest(XHR):最早原生的获取服务端数据的HTTP技术。
- JQuery-AJAX:JQuery中对
XMLHttpRequest
的封装,让调用更简便。 - axios:也是基于
XMLHttpRequest
封装的第三方封装库,是一个轻量的HTTP客户端。还支持拦截请求和响应、转化请求数据和响应数据、中断请求、自动转换JSON数据、客户端支持防御XSRF等。 - FetchAPI:新一代用于替代XHR的技术。
XMLHttpRequest(XHR) | JQuery-AJAX | axios | Fetch API | |
---|---|---|---|---|
描述 | 原生的服务端HTTP调用 | 基于XHR的封装 | 基于XHR的Promise封装 | 新时代的XHR替代者 |
来源 | 原生 | 第三方库 | 第三方库 | 原生 |
特点 | 兼容性好 | 支持jsonp |
综合不错 | 年轻 |
异步 | 基于事件的异步 | 基于事件的异步 | Promise异步 | 标准 Promise异步,支持 async/await |
调用 | request.send() |
$.ajax({url}) |
axios.get(url).then() |
fetch(url).then() |
易用性 | 稍复杂 | 调用简单 | 调用简单 | 调用简单 |
缺点 | 回调地狱 | 回调地狱+组件大 | 有些不完善,如错误的处理、中止、超时等还不足。 | |
总结 | 不推荐了 | 用的逐渐变少了 | VUE中推荐的,比较流行 | 可用IE? |
1.1、XHR(XMLHttpRequest)
XMLHttpRequest(XHR) 是最早提供的获取服务端数据的方式,支持json
、xml
、html
、text
等格式。缺点是使用比较繁琐,很多参数,需要考虑不同浏览器兼容性。
✅XMLHttpRequest属性 | 描述 |
---|---|
response | 响应的数据,类型取决于responseType |
responseType | 定义响应类型的枚举值:blob 、json 、text 、document 、arraybuffer |
readyState | 当前请求所处的状态:0=UNSENT,3=LOADING,4=DONE(已下载完成) |
status | 响应状态码(200=成功),statusText 为完整状态信息 |
timeout | 超时时长(毫秒),超时则会自动终止 |
✅方法 | |
abort() | 中止请求 |
open(method, url) | 初始化一个请求:request.open('GET', "url"); |
send([body]) | 发送 HTTP 异步请求,可选参数 body 包含了 request body |
✅事件 | |
error | 遭遇错误时触发,。 也可以使用 onerror |
load | 求成功完成时触发, 也可以使用 onload |
progress | 当请求接收到更多数据时,周期性地触发 |
let request = new XMLHttpRequest(); | |
request.open('GET', "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json"); | |
// request.open('GET', "hhttps://somewhere.org/i-dont-exist"); | |
request.responseType = 'json'; | |
request.onload = function () { | |
console.log(request.status); //200 | |
console.log(request.readyState); //4 //DONE | |
console.log(request.responseType); //json | |
console.log(request.response) | |
} | |
request.onerror = (e) => { | |
console.log(e.type); | |
} | |
request.send(); |
1.2、Fetch API
Fetch API (IE?) ( fetch /fetʃ/ 提取)是浏览器的底层提供的API,代替XHR,提供了一套简单、异步、支持跨域的HTTP调用方法。
语法:
Promise<Response> fetch(input[, init]);
input
:url地址或Request对象。init
:一个配置项对象,包括所有对请求的设置。
?主要缺点是:
- 对于详细的错误需要自行封装处理,404、500时Promise的状态依然为resolve。
- 默认不支持cookie(可配置),不支持超时控制、不支持中止、不支持请求进度监控。
?fetch 中的Response对象:
✅Response属性 | 描述 |
---|---|
headers | 获取 Headers 对象 |
ok | 布尔值,表明响应是否成功(状态码在 200-299 范围内) |
status | 响应的状态代码,对应状态码消息属性为statusText |
type | 响应类型:basic(标准值)、cors(跨域请求)、error(网络错误) |
url | 响应的url地址 |
✅方法 | |
json() | 接收一个 Response 流,解析为json |
text() | 接收一个 Response 流,解析为UTF-8编码的文本 |
formData() | 解析为FormData对象 |
blob() | 解析为Blob的二进制数据 |
arrayBuffer() | 解析为ArrayBuffer |
window.fetch("https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json") | |
.then((response) => { | |
// step1:检查响应状态是否正常 | |
console.log(response.ok); //true 需判断返回状态 | |
console.log(response.status); //200 | |
console.log(response.url); | |
console.log(response.type); | |
// step2:如状态正常,则解析数据 | |
return response.json(); | |
}) | |
.then(json => { | |
console.log(json); | |
}) | |
.catch(e => console.log(e)); |
1.3、Axios
Axios 是一个基于XMLHttpRequest 实现了异步promise
的网络请求库 ,使用比较简洁。支持的方法主要有get()
,post()
,put()
,patch()
,delete()
。
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> | |
<script> | |
axios.get('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json') | |
.then(response => { | |
console.log(response); | |
console.log(response.status); | |
console.log(response.data); | |
}) | |
.catch(e => { | |
console.log(e); | |
}) | |
</script> |
1.4、JQuery-AJAX
JQuery中的AJAX就是对XHR的封装,简化了调用、封装了兼容性,支持JSONP(实现跨域请求)。缺点的话可能就是库比较大,存在回调地域的小问题。
const url="https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json"; | |
$.ajax({ | |
type: 'GET', | |
url: url, | |
data: null, | |
dataType: "json", | |
success: function (result) { | |
console.log(result); | |
}, | |
error: function (e) { }, | |
}); | |
//更简单的用法 | |
$.getJSON(url,(result)=>{ | |
console.log(result); | |
}); |
02、客户端数据存储
HTTP是无状态的协议,导致客户端的每次请求都是独立的,没有上下文联系,无法确认用户身份,cookie
和session
就是为了解决这个问题。为了解决本地存储问题,HTML5新增了Web Storage解决方案,包括sessionStorage
和localStorage
,以及比较新的IndexedDB
、CacheStorage
。
cookies | localStorage | sessionStorage | |
---|---|---|---|
描述 | 服务端+本地存储的数据 | 本地数据存储 | 本地会话数据存储 |
作用范围 | 同源共享 | 同源共享 | 仅当前文档有效,一夫一妻(刷新有效的) |
生命周期 | 随页面,或设置的过期时间 | 理论上永久有效的 | 随网页,网页关闭会被清除 |
存储大小 | 4K(一个cookie值),一个域名最多50个cookie | 约5MB(不同浏览器情况不同,safari 2.49M) | 约5MB(有些浏览器无限制) |
存储位置 | 保存在客户端 | 保存在客户端,不与服务端交互 | 保存在客户端 |
与服务端 | 每次请求都会发回服务端 | 不与服务端通信 | 不与服务端通信 |
安全性 | 发往服务端+明文,不安全 | 不传输>安全 | 不传输>安全 |
操作方式 | document.cookie 字符串使用不便,需第三方JS库 |
window.localStorage 有简洁的API |
window.sessionStorage API同localStorage |
兼容性 | 非常良好,都支持 | IE8 | IE8 |
使用场景 | 管理认证信息;记住上一次访问时间 | 持久化保存的静态数据: - 个性化配置、搜索历史 - 一些静态不变的图片 |
临时数据:页面表单输入的内容,避免刷新丢失;单页应用的页面路由。 |
性能 | 影响较大,每次请求都要携带 | - | - |
2.1、Cookie传统手艺
HTTP Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,当然本地也可以修改,它会在浏览器下次向同一服务器再发起请求时发送回去。cookie已过时,存在各种安全问题、无法存储复杂数据,推荐使用WebStorage。
?使用场景:
- 会话状态管理:如用户登录状态、购物车、游戏分数或其它需要记录的信息。
- 个性化设置:如用户自定义设置、主题等。
- 浏览器行为跟踪:如跟踪分析用户行为,推送广告等。
?生命周期:随页面的生命周期max-age,页面关闭也失效了,或者设置的过期时间。
- Expires过期时间(本地时间),或
max-age
:Set-Cookie: Expires=Wed, 21 Oct 2015 07:28:00 GMT
?作用范围:同源共享,默认同一域名内的页面共享cookie数据。
- Domain、Path标识作用域可设置作用域范围:
Set-Cookie: Domain=example.com; Path=/
- Domain:主机,主域名,包含子域名。不指定则为Origin(同源),不包含子域名
- Path:URL路径,包含子路径,如,Path=/docs
?安全性:每次都发回服务器,明文传输,不安全
- Secure属性:只有HTTPS才会发送。
Set-Cookie: Secure;HttpOnly;
- HttpOnly属性:不可被JS访问,只用于服务端。
- SameSite,设置Cookie的发送范围,枚举值:
- None:无限制,都发送
- Strict(/strɪkt/ 严格的),相同域名站点才发送,阻止跨站伪造攻击(CSRF)
- Lax( /læks/宽松的 ),与Stric类似,允许外部过来的URL。
(CSRF)跨站攻击例子,如下代码
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory"> |
当你打开有这个图片元素的网页时(非法论坛、钓鱼网站),他会向银行发起转账请求,而你正好刚刚登录了这个银行,cookie保留了登录认证信息。
?食用步骤:
- 服务器在响应头里面添加 Set-Cookie 选项
- 览器会保存Cookie,之后每次请求中都通过请求头部将 Cookie 信息发送给服务器。
Response Headers | |
200 OK | |
Content-type: text/html | |
Set-Cookie: yummy_cookie=choco; Domain=example.com | |
Set-Cookie: tasty_cookie=strawberry;Path=/ | |
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;Secure;HttpOnly; | |
Request Headers | |
GET /sample_page.html HTTP/1.1 | |
Host: www.example.org | |
Cookie: yummy_cookie=choco; tasty_cookie=strawberry | |
?存储与使用:
- document.cookie:返回当前文档关联的cookie数据。值为一个字符串,为键值形式的字符串,
"key=value;key=value;..."
。操作不太方便,一般使用扩展JS库来操作,如js-cookie。 - 存储大小:一个cookie 4K
- 编码存储:cookie的值是需要url编码,
window.encodeURIComponent(str)
编码、window.decodeURIComponent(str)
解码。
document.cookie = "user=sam"; // 只会更新名称为 user 的 cookie | |
document.cookie = "id=10;max-age=10"; //10s立即过期 | |
console.log(document.cookie);//获取所有cookie:user=sam; id=10 |
2.2、session服务端会话
session是一种由服务端为主存储和管理的文档会话信息的机制,多用来管理用户认证信息。session是基于cookie实现的,session存储在服务器端(所以相比cookie更安全),sessionId 被存储到客户端cookie 中。不过sessionId 也可以用其他方式实现传输,如url参数。
?基本流程:
- 登录成功后,服务端创建session并保存。
- 网页会话cookie中保存session的sessionId ,作为客户端身份id。
- 向服务端请求时,服务端会根据sessionId 判断客户端的身份。
2.3、localStorage
window.localStorage 存储同源文档的数据,数据对象Storage 同sessionStorage,特点是数据可以长期保留。
?存储:
- 本地存储,长期保留不会清除,除非你主动抛弃。
- 字符键值:键值都必须是字符串,会自动转换字符(所以要注意对象要手动JSON.stringify())。
- 5M大小,一般大约5M,不同浏览器不同。
?作用范围:同源共享,同一域名下,同端口、同http协议共享数据
- http、https不同,分开存储
?操作API:使用简洁
Storage属性/方法 | 描述 |
---|---|
length | 存储的项目数量 |
setItem(key,value) | 添加/修改数据值 |
getItem(key) | 获取数据值 |
key(n) | 获取第n个key |
removeItem(key) | 移除数据项 |
clear() | 清空 |
window.localStorage.setItem("uid",1122); | |
const uid= localStorage.getItem("uid"); | |
localStorage.removeItem("uid"); | |
localStorage.clear(); | |
//添加storage的变更监听事件,触发变更的页面不会触发事假,其他同域名的页面才会 | |
window.addEventListener("storage", function (e) {}); |
2.4、sessionStorage
window.sessionStorage存储当前文档会话的session数据,数据结构为Storage对象(同localStorage,因此操作API也相同 ),特点是会话结束(页面关闭)数据就清掉了,与页面同生共死。
?存储:
- 本地存储,与页面同生共死:同页面的生命周期,页面关闭就清掉。页面重新加载、恢复会保持会话。
- 字符键值:键值都必须是字符串,会自动转换字符(所以要注意对象要手动JSON.stringify())。
- 5M大小,一般大约5M,不同浏览器不同。
?作用范围:仅当前文档有效,一夫一妻。
- 多个页面独立会话:多个页面(页签)拥有独立的会话sessionStorage,即使是同样的URL地址。
- 新页面复制会话:在当前页面打开的页面,会复制其上下文作为新的会话上下文。
- http、https不同,分开存储。
?使用场景:当前网页一些临时的数据,如网页中表单填写的数据。
window.sessionStorage.setItem("uid", 1122); | |
window.sessionStorage.setItem("uid", {"id":33}); | |
console.log(sessionStorage.getItem("uid"), sessionStorage.length); //1122 1 | |
sessionStorage.clear(); |
2.5、IndexedDB
IndexedDB(IE10)是一个比较完整的事务型、key-value数据结构的前端数据库,类似于基于 SQL 的 RDBMS,可存储复杂数据,包括对象,甚至媒体文件,适用于存储大量数据、且离线使用的场景。
主要特点:
- 键值存储:IndexedDB的数据是以键值形式存储的,键是唯一的且不可重复。
- 空间大:存储空间大(>250MB+)
- 长久保存:数据长久保存,除非主动清除。
- 其他特点:支持异步、支持事务、支持同源数据隔离,有很多第三方库可用,操作更简便。
*CacheStorage
Cache API(IE?)是一种客户端缓存存储机制,可用来实现请求数据离线功能,常在 serviceworker 中搭配 Fetch 使用,实现WEB系统的离线使用。
03、BOM浏览器模型
BOM:Browser Object Model,浏览器对象模型。BOM分为window
对象和window
子对象,其核心就是window
对象,window
对象是BOM顶层对象,为浏览器的实例,是JS访问浏览器的入口。
BOM同时也是ECMAScript规定的Global对象,就是说在网页任何地方都可以访问window
对象。如果一个页面中包含多个frame
,则每个框架frame
都有自己的window
,通过window.frames
的索引、或者框架名称访问。
3.1、window窗口
Window表示一个包含 DOM 文档的窗口,window作为顶级全局变量,提供了很多全局属性和方法,使用时可以省略前面的window.
。
✅普通属性 | 描述 |
---|---|
name | 窗口window的名称 |
innerWidth、innerHeight | 浏览器窗口内部(文档部分)宽度、高度,包括滑动条。 |
outerHeight、outerWidth | 整个浏览器窗口的高度、宽度 |
fullScreen | 是否全屏显示 |
frameElement | 嵌入当前window对象的元素 (比如 <iframe> 或者 <object> ) |
scrollX、scrollY | 水平、垂直滑动条的位置 |
devicePixelRatio | 设备物理分辨率与CSS向上分辨率比例,物理像素/ 设备独立像素 |
✅对象属性 | |
document | 当前窗口内的文档 |
console | 浏览器控制台调试接口 |
history | history 对象 |
location | location 对象 |
localStorage | 本地存储localStorage,可长期存储 |
sessionStorage | session会话存储,页面关闭就没了 |
navigator | 表示用户代理的状态和标识,浏览器环境信息 |
parent、top | 父窗口、最顶层窗口,window.parent === window.top //false 说明多级嵌套 |
screen | 设备屏幕信息,包含width、height、colorDepth等属性。 |
caches | 当前上下文的 CacheStorage 对象 |
✅方法 | |
alert(message) | 弹出消息提示框 |
prompt(mes,value) | 弹出一个输入提示框,返回输入的值。prompt/prɒmpt/提词、提示 |
confirm(message) | 弹出询问的确认框,返回“确定”(true)、“取消”(false) |
open(url,target,fetures) | 打开一个URL地址,类似点击a标签open("http://www.baidu.com","_blank"); |
close() | 关闭当前窗口 |
fetch(url) | 异步HTTP请求,返回一个Promise对象 |
getSelection() | 获取选中的内容 Selection 对象 |
print() | 打印 |
getComputedStyle(element) | 获取其所有CSS样式属性值 |
postMessage(mes,target) | 窗口间发送消息,可安全的实现跨域通信。 |
requestAnimationFrame(func) | 浏览器为动画帧重新绘制窗口,回调函数频率一般每秒 60 次,或者同浏览器的刷新次数。为提高性能,窗口隐藏时一般会被浏览器暂停执行。cancelAnimationFrame(id) 取消 |
scroll(x, y) | 滚动窗口到指定的x、y坐标,和scrollTo (x, y)一样。 |
scrollBy(x, y) | 滚动窗口按x、y偏移量 |
✅时间函数 | |
setTimeout(func,times,args?) | 延迟执行:在指定的毫秒数后执行函数,返回唯一标识(用于取消)。 |
clearTimeout(id) | 通过setTimeout的唯一标识,可以取消执行函数。 |
setInterval(func,times,asgs) | 周期执行:固定周期的执行函数,返回唯一标识,直到clearInterval清除或窗口关闭。 |
clearInterval(id) | 根据唯一标识清除setInterval固定周期的函数 |
✅事件 | |
online | 网络连接时触发 |
offline | 网络断开时触发 |
let id; | |
const htime = document.getElementById("h22"); | |
//实现时钟更新效果,套娃,调用栈存在问题?现在这种没有参数可以,带了参数就不行了(会形成闭包) | |
function upDateTime() { | |
h2.innerHTML = new Date().toLocaleString(); | |
id = window.setTimeout(upDateTime, 1000); | |
} | |
function btnStart() { //开始计时 | |
id = window.setTimeout(upDateTime, 0); | |
} | |
function btnStop() { //停止计时 | |
console.log(id); | |
window.clearTimeout(id); | |
} | |
//setInterval 实现时钟 | |
window.setInterval(()=>{ | |
htime.innerHTML = new Date().toLocaleString(); | |
},1000) |
3.2、navigator环境信息
navigator属性 | 描述 |
---|---|
appName | 浏览器名称 |
appVersion | 浏览器版本 |
language | 浏览器设置的语言 |
platform | 操作系统类型,//Win32 |
userAgent | 浏览器设定的User-Agent字符串,一般用来判断浏览器版本,虽然可能不准确。 |
online | 判断是否联网 |
... | 其他还有如geolocation(地理)、connection(网络)、maxTouchPoints(触摸) |
navigator方法 | 描述 |
sendBeacon(url, data) | 在后台发送一个HTTP请求(POST方式),比如在关闭页面前beforeunload 发送数据 |
navigator的代理信息
userAgent
并不准确,因为可以被用户修改,不适合用来判断浏览器版本。兼容性属性可以用属性是否存在来判断,或者第三方框架。
3.3、history历史
history 是历史对象,存放当前文档页面(或框架)的会话历史记录(不是浏览器的所有历史记录)。
history 属性/方法 | 描述 |
---|---|
length | 会话历史列表的记录数量 |
state | 表示历史堆栈顶部记录的状态值,可以是任意可序列化JavaScript对象,限制为2MB |
pushState(stateObj, title[, url]) | 向当前会话的历史堆栈中添加一条记录 |
replaceState(stateObj, title[, url]) | 修改 history 对象的当前记录 |
back() | 返回到(历史列表中)上一个URL地址。 |
forward() | 前进,加载(历史列表中)下一个URL地址 |
go(number) | 加载指定相对当前网页索引位置的历史列表URL地址,go(-1)等同于back() |
pushState
、replaceState
是HTML5在history
上新增的API,用来新增、修改当前文档的历史记录,这两个API就是用来实现SPA单页应用前端路由的关键。他们的参数相同:
- state:一个关联历史会话记录的状态对象,在触发
popstate
事件时作为参数传递,不需要可以为null
,通过history.state
可以获取到当前会话的state
。 - title:新页面的标题,大部分浏览器都没有管他,可以空着。
- url:网址,可以相对、绝对地址,但不可跨域。这个url 会更新到浏览器地址栏,但并不会加载该Url地址,也不检查是否存在,页面也不会刷新!
3.4、location地址
location也是window下的对象,提供了与当前窗口文档URL地址有关的信息,用来实现页面跳转。
location属性/方法 | 描述 |
---|---|
href | 返回或设置当前页面完整URL地址 |
pathname、search | url的一部分,路径、参数 |
protocol、host 、port | 域名的组成:通信协议,服务端名称、端口号,完整的域名属性origin |
hash | URL中# 号后面的内容,hashchange 事件可监测hash 变化 |
reload() | 重新加载页面文档,刷新 |
assign(url) | 加载指定url页面 |
replace(url) | 用新的文档替换当前文档,不会保存历史记录(所以不能后退) |
©️版权申明:版权所有@安木夕,