Skip to content

Latest commit

 

History

History
335 lines (225 loc) · 14.2 KB

网络请求.md

File metadata and controls

335 lines (225 loc) · 14.2 KB

网络请求

http缓存

Window.localStorage

  • 只读的 localStorage 属性允许你访问一个 Document 源(origin)的对象 Storage
  1. localStorage 中的键值对总是以字符串的形式存储。
  2. 存储在 localStorage 的数据可以长期保留
.length .key()
// 增加了一个数据项目
localStorage.setItem('myCat', 'Tom')

// 该语法用于读取 localStorage 项,如下:
let cat = localStorage.getItem('myCat')

// 该语法用于移除 localStorage 项,如下:
localStorage.removeItem('myCat')

// 该语法用于移除所有的 localStorage 项,如下:
localStorage.clear()
  • sessionStorage 属性允许你访问一个,对应当前源的 session Storage 对象。
  1. 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
  2. 关闭对应浏览器标签或窗口,会清除对应的 sessionStorage。
  3. 打开多个相同的 URL 的 Tabs 页面,会创建各自的 sessionStorage。
  4. 被存储的键值对总是以 UTF-16 DOMString 的格式所存储,其使用两个字节来表示一个字符。(字符串)

[!] http://example.comhttps://example.com 的 sessionStorage 相互隔离。

.length .key()
// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');

// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');

// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');

// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();

localStorage & sessionStorage 区别

localStorage sessionStorage
留存机制 可以长期保留 页面被关闭时被清除
语法 继承 Storage 原型的方法 继承 Storage 原型的方法
存储大小 一般都是 5Mb 不同浏览器不同 5Mb

负载均衡器

是一种把网络请求分散到一个服务器集群中的可用服务器上去,通过管理进入的 Web 数据流量和增加有效的网络带宽的硬件设备。

Fetch

对于来自 JavaScript 的网络请求,有一个总称术语 “AJAX”(Asynchronous JavaScript And XML 的简称)。但是,==我们不必使用 XML==:这个术语诞生于很久以前,所以这个词一直在那儿。

fetch() 方法是一种现代通用的方法,那么我们就从它开始吧。旧版本的浏览器不支持它(可以 polyfill),但是它在现代浏览器中的支持情况很好。

基本语法:

let promise = fetch(url, [options])
  • url —— 要访问的 URL。
  • options —— 可选参数:method,header 等。

没有 options,这就是一个简单的 ==GET== 请求,下载 url 的内容。

浏览器立即启动请求,并返回一个该调用代码应该用来获取结果的 promise

==第一阶段== 当服务器发送了响应头(response header),fetch 返回的 promise 就使用内建的 Response class 对象来对响应头进行解析。

在这个阶段,我们可以通过==检查响应头==,来==检查 HTTP 状态==以确定请求是否成功,当前还没有响应体(response body)。

如果 fetch 无法建立一个 HTTP 请求,例如网络问题,亦或是请求的网址不存在,那么 promise 就会 ==reject==。异常的 HTTP 状态,例如 404 或 500,不会导致出现 error。

我们可以在 response 的属性中看到 HTTP 状态:

  • status —— HTTP 状态码,例如 200。
  • ok —— 布尔值,如果 HTTP 状态码为 200-299,则为 true

例如:

let response = await fetch(url)

if (response.ok) {
  // 如果 HTTP 状态码为 200-299
  // 获取 response body(此方法会在下面解释)
  let json = await response.json()
} else {
  alert('HTTP-Error: ' + response.status)
}

==第二阶段== 为了获取 response body,我们需要使用一个其他的方法调用。

Response 提供了多种基于 promise 的方法,来以不同的格式访问 body:

  • response.text() —— 读取 response,并以文本形式返回 response,
  • response.json() —— 将 response 解析为 JSON,
  • response.formData() —— 以 FormData 对象(在 下一章 有解释)的形式返回 response,
  • response.blob() —— 以 Blob(具有类型的二进制数据)形式返回 response,
  • response.arrayBuffer() —— 以 ArrayBuffer(低级别的二进制数据)形式返回 response,
  • 另外,response.bodyReadableStream 对象,它允许你逐块读取 body,我们稍后会用一个例子解释它。

==重要:==

我们只能选择一种读取 body 的方法。

如果我们已经使用了 response.text() 方法来获取 response,那么如果再用 response.json(),则不会生效,因为 body 内容已经被处理过了。

let text = await response.text() // response body 被处理了
let parsed = await response.json() // 失败(已经被处理过了)

[POST 请求]

要创建一个 POST 请求,或者其他方法的请求,我们需要使用 fetch 选项:

  • method —— HTTP 方法,例如 POST
  • body —— request body,其中之一:
    • 字符串(例如 JSON 编码的),
    • FormData 对象,以 multipart/form-data 形式发送数据,
    • Blob/BufferSource 发送二进制数据,
    • URLSearchParams,以 x-www-form-urlencoded 编码形式发送数据,很少使用。

JSON 形式是最常用的。

例如,下面这段代码以 ==JSON 形式== 发送 user 对象:

let user = {
  name: 'John',
  surname: 'Smith',
}

let response = await fetch('/article/fetch/post/user', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json;charset=utf-8',
  },
  body: JSON.stringify(user),
})

let result = await response.json()
alert(result.message)

请注意,如果请求的 body 是字符串,则 Content-Type 会默认设置为 text/plain;charset=UTF-8

但是,当我们要发送 JSON 时,我们会使用 headers 选项来发送 application/json,这是 JSON 编码的数据的正确的 Content-Type


总结:

典型的 fetch 请求由两个 await 调用组成:

let response = await fetch(url, options) // 解析 response header
let result = await response.json() // 将 body 读取为 json

或者以 promise 形式:

fetch(url, options)
  .then(response => response.json())
  .then(result => /* process result */)

响应的属性:

  • response.status —— response 的 HTTP 状态码,
  • response.ok —— HTTP 状态码为 200-299,则为 true
  • response.headers —— 类似于 Map 的带有 HTTP header 的对象。

获取 response body 的方法:

  • response.text() —— 读取 response,并以文本形式返回 response,
  • response.json() —— 将 response 解析为 JSON 对象形式,
  • response.formData() —— 以 FormData 对象(multipart/form-data 编码,参见下一章)的形式返回 response,
  • response.blob() —— 以 Blob(具有类型的二进制数据)形式返回 response,
  • response.arrayBuffer() —— 以 ArrayBuffer(低级别的二进制数据)形式返回 response。

到目前为止我们了解到的 fetch 选项:

  • method —— HTTP 方法,
  • headers —— 具有 request header 的对象(不是所有 header 都是被允许的)
  • body —— 要以 stringFormDataBufferSourceBlobUrlSearchParams 对象的形式发送的数据(request body)。

JWT 用户验证

JWT 是一种认证协议 JWT 就是个生成 token(用户令牌)的一个规范。 JSON Web Token 是什么 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JWT 与 Session 的差异 相同点是,它们都是存储用户信息; 然而,Session 是在服务器端的,而 JWT 是在客户端的。 Session 方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。

JSON Web Token 的结构是什么样的

Header Payload Signature 一个典型的 JWT 看起来是这个样子的: xxxxx.yyyyy.zzzzz JWT

JWT 的 Payload 里面可以设置一个过期时间, 我们可以在用户每次访问的时候==把这个过期时间更新一下==。

JWT

用解码的方式鉴权,用算法开销替代存储开销 JWT

JWT 是如何工作的

在认证的时候,当用户用他们的凭证成功登录以后,一个 JSON Web Token 将会被返回。此后,token 就是用户凭证了,你必须非常小心以防止出现安全问题。一般而言,你保存令牌的时候不应该超过你所需要它的时间。

用 Token 的好处

  • 无状态和可扩展性:Tokens 存储在客户端。完全无状态,可扩展。我们的负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息。
  • token 在一段时间以后会过期,这个时候用户需要重新登录。这有助于我们保持安全。

JWT 与 OAuth 的区别

  • OAuth2 是一种授权框架 ,JWT 是一种认证协议 -无论使用哪种方式切记用 HTTPS 来保证数据的安全性
  • OAuth2 用在使用==第三方账号==登录的情况(比如使用 weibo, qq, github 登录某个 app),
  • 而 JWT 是用在前后端分离, 需要简单的对后台 API 进行保护时使用。

浏览器安全功能

同源策略(Same origin policy)

是一种约定,它是浏览器最核心也最基本的安全功能。==这能有效的阻止跨站攻击。== 所谓同源是指,域名,协议,端口相同。 非同源的客户端脚本在没有明确授权的情况下,不能读写对方资源,在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

非同源受到的限制:

cookie 不能读取 dom 无法获得 ajax 请求不能发送

什么是跨域:

==当前源(域名、协议、端口)== 跨域是指跨域名的访问,以下情况都属于跨域: 跨域原因说明 示例 域名不同 www.jd.comwww.taobao.com 域名相同,端口不同 www.jd.com:8080www.jd.com:8081 二级域名不同 http://item.jd.comhttp://miaosha.jd.com 如果域名和端口都相同,但是请求路径不同,不属于跨域,如: www.jd.com/item www.jd.com/goods

注意: http://localhosthttp://127.0.0.1 也不是同域哦

跨域问题是浏览器对于 ajax 请求的一种安全限制:一个页面发起的 ajax 请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。

因此:跨域问题 ==是针对 ajax 的一种限制==。

JSONP:

而动态添加一个<script>标签,script 标签的 src 属性是==没有跨域的限制==的。 我们可以通过使用 html 的 script 标记来进行跨域请求,并在响应中返回要执行的 script 代码,其中可以直接使用 JSON 传递 javascript 对象,这种跨域的通讯方式称为 JSONP。

CORS(Cross-Origin Resource Sharing 跨源资源共享)

跨源资源共享 (CORS)(或通俗地译为跨域资源共享) 是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源。 (即浏览器与不同的服务器资源交换)

  • CORS 需要浏览器和服务器同时支持,才可以实现跨域请求,目前几乎所有浏览器都支持 CORS
  • CORS 的整个过程都由==浏览器自动完成==,==前端无需做任何设置==,跟平时发送 ajax 请求并无差异。
  • 它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。

什么情况下需要 CORS ?

  • 前文提到的由 XMLHttpRequest 或 Fetch APIs 发起的跨源 HTTP 请求。
  • ==Web 字体== (CSS 中通过 @font-face 使用跨源字体资源),因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
  • ==WebGL 贴图==
  • 使用 drawImage 将 Images/video 画面绘制到 canvas。 来自图像的 CSS 图形

网络安全

网络攻击

CSRF:(Cross Site Request Forgery, 跨站域请求伪造)

尽管听起来像跨站脚本(XSS),但它与 XSS 非常不同,并且攻击方式几乎相左。XSS 利用站点内的信任用户,而 CSRF 则通过伪装来自受信任用户的请求来利用受信任的网站。与 XSS 攻击相比,CSRF 攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比 XSS 更具危险性。 CSRF

API 接口设计

RESTful (Representational State Transfer)

如果一个架构符合 REST 原则,就称它为 RESTful 架构 RESTful 架构可以充分的利用 HTTP 协议的各种功能,是 HTTP 协议的最佳实践 RESTful API 是一种==软件架构风格、设计风格==,可以让软件更加清晰,更简洁,更有层次,可维护性更好

底部 bottom ^^