Html 本地存储与 Cookie
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3220660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Local Storage vs Cookies
提问by Gio Borje
I want to reduce load times on my websites by moving all cookies into local storage since they seem to have the same functionality. Are there any pros/cons (especially performance-wise) in using local storage to replace cookie functionality except for the obvious compatibility issues?
我想通过将所有 cookie 移动到本地存储来减少我网站的加载时间,因为它们似乎具有相同的功能。除了明显的兼容性问题外,使用本地存储替换 cookie 功能是否有任何优点/缺点(尤其是在性能方面)?
回答by jpsimons
Cookies and local storage serve different purposes. Cookies are primarily for reading server-side, local storage can only be read by the client-side. So the question is, in your app, who needs this data — the client or the server?
Cookie 和本地存储用于不同的目的。Cookies主要用于服务端读取,本地存储只能由客户端读取。所以问题是,在你的应用程序中,谁需要这些数据——客户端还是服务器?
If it's your client (your JavaScript), then by all means switch. You're wasting bandwidth by sending all the data in each HTTP header.
如果它是您的客户端(您的 JavaScript),那么一定要切换。通过发送每个 HTTP 标头中的所有数据,您正在浪费带宽。
If it's your server, local storage isn't so useful because you'd have to forward the data along somehow (with Ajax or hidden form fields or something). This might be okay if the server only needs a small subset of the total data for each request.
如果它是您的服务器,本地存储就不是那么有用,因为您必须以某种方式转发数据(使用 Ajax 或隐藏表单字段或其他东西)。如果服务器只需要每个请求的总数据的一小部分,这可能没问题。
You'll want to leave your session cookie as a cookie either way though.
不管怎样,您都希望将会话 cookie 保留为 cookie。
As per the technical difference, and also my understanding:
根据技术差异,以及我的理解:
Apart from being an old way of saving data, Cookies give you a limit of 4096bytes (4095, actually) — it's per cookie. Local Storage is as big as 5MB per domain— SO Questionalso mentions it.
localStorage
is an implementation of theStorage
Interface. It stores data with no expiration date, and gets cleared onlythrough JavaScript, or clearing the Browser Cache / Locally Stored Data — unlike cookie expiry.
除了作为一种旧的数据保存方式之外,Cookie 还为您提供了4096字节(实际上是 4095)的限制——它是每个 cookie。每个域的本地存储空间高达5MB— SO Question也提到了这一点。
localStorage
是Storage
接口的实现。它存储的数据没有过期日期,并且只能通过 JavaScript清除,或者清除浏览器缓存/本地存储的数据——与 cookie 过期不同。
回答by XtraSimplicity
In the context of JWTs, Stormpath have written a fairly helpful article outlining possible ways to store them, and the (dis-)advantages pertaining to each method.
在 JWT 的上下文中,Stormpath 写了一篇非常有用的文章,概述了存储它们的可能方法,以及与每种方法有关的(缺点)优点。
It also has a short overview of XSS and CSRF attacks, and how you can combat them.
它还简要概述了 XSS 和 CSRF 攻击,以及如何对抗它们。
I've attached some short snippets of the article below, in case their article is taken offline/their site goes down.
我附上了下面文章的一些简短片段,以防他们的文章离线/他们的网站关闭。
Local Storage
本地存储
Problems:
问题:
Web Storage (localStorage/sessionStorage) is accessible through JavaScript on the same domain. This means that any JavaScript running on your site will have access to web storage, and because of this can be vulnerable to cross-site scripting (XSS) attacks. XSS in a nutshell is a type of vulnerability where an attacker can inject JavaScript that will run on your page. Basic XSS attacks attempt to inject JavaScript through form inputs, where the attacker puts alert('You are Hacked'); into a form to see if it is run by the browser and can be viewed by other users.
Web Storage (localStorage/sessionStorage) 可以通过 JavaScript 在同一个域中访问。这意味着在您的站点上运行的任何 JavaScript 都可以访问 Web 存储,因此可能容易受到跨站点脚本 (XSS) 攻击。简而言之,XSS 是一种漏洞,攻击者可以在其中注入将在您的页面上运行的 JavaScript。基本的 XSS 攻击尝试通过表单输入注入 JavaScript,攻击者在其中放置 alert('You are Hacked'); 成一个表单,看看它是否由浏览器运行,是否可以被其他用户查看。
Prevention:
预防:
To prevent XSS, the common response is to escape and encode all untrusted data. But this is far from the full story. In 2015, modern web apps use JavaScript hosted on CDNs or outside infrastructure. Modern web apps include 3rd party JavaScript libraries for A/B testing, funnel/market analysis, and ads. We use package managers like Bower to import other peoples' code into our apps.
What if only one of the scripts you use is compromised? Malicious JavaScript can be embedded on the page, and Web Storage is compromised. These types of XSS attacks can get everyone's Web Storage that visits your site, without their knowledge. This is probably why a bunch of organizations advise not to store anything of value or trust any information in web storage. This includes session identifiers and tokens.
As a storage mechanism, Web Storage does not enforce any secure standards during transfer. Whoever reads Web Storage and uses it must do their due diligence to ensure they always send the JWT over HTTPS and never HTTP.
为了防止 XSS,常见的反应是对所有不受信任的数据进行转义和编码。但这远非故事的全部。2015 年,现代 Web 应用程序使用托管在 CDN 或外部基础架构上的 JavaScript。现代网络应用程序包括用于 A/B 测试、漏斗/市场分析和广告的 3rd 方 JavaScript 库。我们使用像 Bower 这样的包管理器将其他人的代码导入到我们的应用程序中。
如果您使用的脚本中只有一个遭到破坏怎么办?恶意 JavaScript 可以嵌入到页面中,并且 Web 存储会受到损害。这些类型的 XSS 攻击可以在每个人不知情的情况下获取访问您站点的每个人的 Web 存储。这可能就是为什么许多组织建议不要在网络存储中存储任何有价值的东西或信任任何信息的原因。这包括会话标识符和令牌。
作为一种存储机制,Web Storage 在传输过程中不强制执行任何安全标准。阅读并使用 Web Storage 的任何人都必须尽职尽责,以确保他们始终通过 HTTPS 而不是 HTTP 发送 JWT。
Cookies
饼干
Problems:
问题:
Cookies, when used with the HttpOnly cookie flag, are not accessible through JavaScript, and are immune to XSS. You can also set the Secure cookie flag to guarantee the cookie is only sent over HTTPS. This is one of the main reasons that cookies have been leveraged in the past to store tokens or session data. Modern developers are hesitant to use cookies because they traditionally required state to be stored on the server, thus breaking RESTful best practices. Cookies as a storage mechanism do not require state to be stored on the server if you are storing a JWT in the cookie. This is because the JWT encapsulates everything the server needs to serve the request.
However, cookies are vulnerable to a different type of attack: cross-site request forgery (CSRF). A CSRF attack is a type of attack that occurs when a malicious web site, email, or blog causes a user's web browser to perform an unwanted action on a trusted site on which the user is currently authenticated. This is an exploit of how the browser handles cookies. A cookie can only be sent to the domains in which it is allowed. By default, this is the domain that originally set the cookie. The cookie will be sent for a request regardless of whether you are on galaxies.com or hahagonnahackyou.com.
Cookie 与 HttpOnly cookie 标志一起使用时,不能通过 JavaScript 访问,并且不受 XSS 的影响。您还可以设置安全 cookie 标志以保证 cookie 仅通过 HTTPS 发送。这是过去利用 cookie 来存储令牌或会话数据的主要原因之一。现代开发人员对使用 cookie 犹豫不决,因为他们传统上要求将状态存储在服务器上,从而破坏了 RESTful 最佳实践。如果您在 cookie 中存储 JWT,作为存储机制的 cookie 不需要将状态存储在服务器上。这是因为 JWT 封装了服务器为请求提供服务所需的一切。
但是,cookie 容易受到不同类型的攻击:跨站点请求伪造 (CSRF)。CSRF 攻击是一种攻击类型,当恶意网站、电子邮件或博客导致用户的 Web 浏览器在用户当前已通过身份验证的受信任站点上执行不需要的操作时,就会发生这种攻击。这是对浏览器如何处理 cookie 的一种利用。cookie 只能发送到允许它的域。默认情况下,这是最初设置 cookie 的域。无论您是在 galaxies.com 还是 hahagonnahackyou.com,都会根据请求发送 cookie。
Prevention:
预防:
Modern browsers support the
SameSite
flag, in addition toHttpOnly
andSecure
. The purpose of this flag is to prevent the cookie from being transmitted in cross-site requests, preventing many kinds of CSRF attack.For browsers that do not support
SameSite
, CSRF can be prevented by using synchronized token patterns. This sounds complicated, but all modern web frameworks have support for this.For example, AngularJS has a solution to validate that the cookie is accessible by only your domain. Straight from AngularJS docs:
When performing XHR requests, the $http service reads a token from a cookie (by default, XSRF-TOKEN) and sets it as an HTTP header (X-XSRF-TOKEN). Since only JavaScript that runs on your domain can read the cookie, your server can be assured that the XHR came from JavaScript running on your domain. You can make this CSRF protection stateless by including a
xsrfToken
JWT claim:{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "[email protected]", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }
Leveraging your web app framework's CSRF protection makes cookies rock solid for storing a JWT. CSRF can also be partially prevented by checking the HTTP Referer and Origin header from your API. CSRF attacks will have Referer and Origin headers that are unrelated to your application.
除了和之外,现代浏览器还支持该
SameSite
标志。这个标志的目的是防止cookie在跨站请求中被传输,防止多种CSRF攻击。HttpOnly
Secure
对于不支持 的浏览器,
SameSite
可以通过使用同步令牌模式来防止 CSRF。这听起来很复杂,但所有现代 Web 框架都支持这一点。例如,AngularJS 有一个解决方案来验证 cookie 只能由您的域访问。直接来自 AngularJS 文档:
执行 XHR 请求时,$http 服务从 cookie(默认为 XSRF-TOKEN)中读取令牌并将其设置为 HTTP 标头 (X-XSRF-TOKEN)。由于只有在您的域上运行的 JavaScript 才能读取 cookie,因此您的服务器可以确信 XHR 来自在您的域上运行的 JavaScript。您可以通过包含
xsrfToken
JWT 声明使此 CSRF 保护无状态:{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "[email protected]", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }
利用 Web 应用程序框架的 CSRF 保护使 cookie 非常适合存储 JWT。通过检查 API 中的 HTTP Referer 和 Origin 标头,也可以部分防止 CSRF。CSRF 攻击将具有与您的应用程序无关的 Referer 和 Origin 标头。
The full article can be found here: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
完整的文章可以在这里找到:https: //stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
They also have a helpful article on how to best design and implement JWTs, with regards to the structure of the token itself: https://stormpath.com/blog/jwt-the-right-way/
他们还有一篇关于如何最好地设计和实现 JWT 的有用文章,关于令牌本身的结构:https://stormpath.com/blog/jwt-the-right-way/
回答by DevWL
With localStorage
, web applications can store data locally within the user's browser. Before HTML5, application data had to be stored in cookies, included in every server request. Large amounts of data can be stored locally, without affecting website performance. Although localStorage
is more modern, there are some pros and cons to both techniques.
使用localStorage
,Web 应用程序可以在用户浏览器中本地存储数据。在 HTML5 之前,应用程序数据必须存储在 cookie 中,包含在每个服务器请求中。可以在本地存储大量数据,不影响网站性能。虽然localStorage
更现代,但这两种技术都有一些优点和缺点。
Cookies
饼干
Pros
优点
- Legacy support (it's been around forever)
- Persistent data
- Expiration dates
- 遗留支持(它一直存在)
- 持久数据
- 到期日期
Cons
缺点
- Each domain stores all its cookies in a single string, which can make parsing data difficult
- Data is unencrypted, which becomes an issue because... ... though small in size, cookies are sent with every HTTP request Limited size (4KB)
- SQL injection can be performed from a cookie
- 每个域都将其所有 cookie 存储在一个字符串中,这会使解析数据变得困难
- 数据未加密,这成为一个问题,因为... ...尽管大小很小,但每个 HTTP 请求都会发送 cookie 大小有限 (4KB)
- 可以从 cookie 执行 SQL 注入
Local storage
本地存储
Pros
优点
- Support by most modern browsers
- Persistent data that is stored directly in the browser
- Same-origin rules apply to local storage data
- Is not sent with every HTTP request
- ~5MB storage per domain (that's 5120KB)
- 大多数现代浏览器都支持
- 直接存储在浏览器中的持久数据
- 同源规则适用于本地存储数据
- 不是随每个 HTTP 请求一起发送
- 每个域约 5MB 存储空间(即 5120KB)
Cons
缺点
- Not supported by anything before: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
- If the server needs stored client information you purposely have to send it.
- 以前不受任何支持:IE 8、Firefox 3.5、Safari 4、Chrome 4、Opera 10.5、iOS 2.0、Android 2.0
- 如果服务器需要存储的客户端信息,您必须特意发送它。
localStorage
usage is almost identical with the session one. They have pretty much exact methods, so switching from session to localStorage
is really child's play. However, if stored data is really crucial for your application, you will probably use cookies as a backup in case localStorage
is not available. If you want to check browser support for localStorage
, all you have to do is run this simple script:
localStorage
用法与会话一几乎相同。他们有非常精确的方法,所以从会话切换到localStorage
真正的孩子们的游戏。但是,如果存储的数据对您的应用程序真的很重要,您可能会使用 cookie 作为备份,以防万一localStorage
。如果你想检查浏览器对 的支持localStorage
,你所要做的就是运行这个简单的脚本:
/*
* function body that test if storage is available
* returns true if localStorage is available and false if it's not
*/
function lsTest(){
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
/*
* execute Test and run our custom script
*/
if(lsTest()) {
// window.sessionStorage.setItem(name, 1); // session and storage methods are very similar
window.localStorage.setItem(name, 1);
console.log('localStorage where used'); // log
} else {
document.cookie="name=1; expires=Mon, 28 Mar 2016 12:00:00 UTC";
console.log('Cookie where used'); // log
}
"localStorage values on Secure (SSL) pages are isolated"as someone noticed keep in mind that localStorage will not be available if you switch from 'http' to 'https' secured protocol, where the cookie will still be accesible. This is kind of important to be aware of if you work with secure protocols.
“安全 (SSL) 页面上的 localStorage 值是隔离的”,因为有人注意到,如果您从“http”切换到“https”安全协议,则 localStorage 将不可用,而 cookie 仍然可以访问。如果您使用安全协议,这一点很重要。
回答by pop850
Well, local storage speed greatly depends on the browser the client is using, as well as the operating system. Chrome or Safari on a mac could be much faster than Firefox on a PC, especially with newer APIs. As always though, testing is your friend (I could not find any benchmarks).
嗯,本地存储速度在很大程度上取决于客户端使用的浏览器以及操作系统。Mac 上的 Chrome 或 Safari 可能比 PC 上的 Firefox 快得多,尤其是使用较新的 API。与往常一样,测试是您的朋友(我找不到任何基准)。
I really don't see a huge difference in cookie vs local storage. Also, you should be more worried about compatibility issues: not all browsers have even begun to support the new HTML5 APIs, so cookies would be your best bet for speed and compatibility.
我真的没有看到 cookie 与本地存储的巨大差异。此外,您应该更担心兼容性问题:并非所有浏览器甚至都开始支持新的 HTML5 API,因此 cookie 将是您提高速度和兼容性的最佳选择。
回答by benjaminz
It is also worth mentioning that localStorage
cannot be used when users browse in "private" mode in some versions of mobile Safari.
还值得一提的是,localStorage
在某些版本的手机Safari中,用户以“私密”模式浏览时无法使用。
Quoted from MDN (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage):
引自 MDN ( https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage):
Note: Starting with iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short. Safari Mobile's Private Browsing mode also prevents writing to localStorage entirely.
注意:从 iOS 5.1 开始,Safari Mobile 将 localStorage 数据存储在缓存文件夹中,该文件夹会根据操作系统的要求偶尔进行清理,通常是在空间不足的情况下。Safari Mobile 的隐私浏览模式也完全阻止写入 localStorage。
回答by Avinash Malhotra
Local storage can store up to 5mb offline data, whereas session can also store up to 5 mb data. But cookies can store only 4kb data in text format.
本地存储最多可以存储 5mb 的离线数据,而 session 也可以存储最多 5 mb 的数据。但是 cookie 只能以文本格式存储 4kb 的数据。
LOCAl and Session storage data in JSON format, thus easy to parse. But cookies data is in string format.
LOCAL 和 Session 以 JSON 格式存储数据,从而易于解析。但是cookies数据是字符串格式的。
回答by Seyedraouf Modarresi
Cookies:
饼干:
- Introduced prior to HTML5.
- Has expiration date.
- Cleard by JS or by Clear Browsing Data of browser or after expiration date.
- Will sent to the server per each request.
- The capacity is 4KB.
- Only strings are able to store in cookies.
- There are two types of cookies: persistent and session.
- 在 HTML5 之前引入。
- 有有效期。
- 由 JS 或通过浏览器的清除浏览数据或过期日期后清除。
- 将每个请求发送到服务器。
- 容量为4KB。
- 只有字符串能够存储在 cookie 中。
- 有两种类型的 cookie:持久的和会话的。
Local Storage:
本地存储:
- Introduced with HTML5.
- Does not has expiration date.
- Cleard by JS or by Clear Browsing Data of the browser.
- You can select when the data must be sent to the server.
- The capacity is 5MB.
- Data is stored indefinitely, and must be a string.
- Only have one type.
- 随 HTML5 引入。
- 没有有效期。
- 由JS或浏览器的Clear Browsing Data清除。
- 您可以选择何时必须将数据发送到服务器。
- 容量为 5MB。
- 数据是无限存储的,必须是字符串。
- 只有一种类型。