服务器端Cookie和客户端Cookie有什么区别?

196

在服务器和客户端创建cookie之间有什么区别?这些被称为服务器端cookie和客户端cookie吗?是否有一种方法可以创建只能在服务器或客户端上读取的cookie?


26
不存在“服务器端cookie”和“客户端cookie”的区别,只有cookie,即在HTTP头中随请求和响应一起发送的名称/值对。 - Dan Grossman
2
可能涉及到会话变量,它们保存在服务器上的数据。通常还会有一个会话标识符作为客户端cookie保存。 - AndrewR
1
很可能,该问题涉及到服务器端编码Cookie的不同方式(即在'Cookie'和'Set-Cookie'响应头中编码的方式)和客户端编码方式(即在“Cookie”请求头中编码的方式——$Path变量等)。请参见RFC 2109 - Ophir Radnitz
2
主要的区别可能在于稍微更改名称:客户端设置和服务器设置的cookie。Cookie在请求和响应中被发送,但主要的区别在于哪一方创建了cookie(或另一个标识会话的ID)。 - Jochem Schulenklopper
5个回答

177

HTTP COOKIES

Cookie是网站用于在浏览器上存储状态信息的键值对。例如,当浏览器请求一个网页时,网站可以发送cookie来在浏览器上存储信息。

浏览器请求示例:

GET /index.html HTTP/1.1
Host: www.example.com

服务器返回的示例答案:

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: foo=10
Set-Cookie: bar=20; Expires=Fri, 30 Sep 2011 11:48:00 GMT
... rest  of the response

这里在浏览器上存储了两个cookie,分别是foo=10和bar=20。第二个cookie将在9月30日过期。 在每个后续请求中,浏览器都会将cookie发送回服务器。

GET /spec.html HTTP/1.1
Host: www.example.com
Cookie: foo=10; bar=20
Accept: */*

SESSIONS: 服务器端的Cookies

服务器端的Cookies被称为“会话”。在这种情况下,网站在浏览器上存储一个包含唯一会话标识符的单个Cookie。状态信息(如上面的foo=10和bar=20)存储在服务器上,并使用会话标识符将请求与存储在服务器上的数据匹配。

使用示例

您可以使用会话和Cookies来存储:身份验证数据、用户首选项、电子商务网站中图表的内容等等...

优缺点

以下是解决方案的优缺点。这些是我首先想到的,肯定还有其他的。

Cookie优点:

  • 可扩展性:所有数据都存储在浏览器中,因此每个请求都可以通过负载均衡器传递到不同的Web服务器,并且您拥有完成请求所需的所有信息;
  • 它们可以通过浏览器上的JavaScript访问;
  • 不在服务器上,因此它们将在服务器重新启动后继续存在;
  • RESTful:请求不依赖于服务器状态

Cookie缺点:

会话优点:

  • 通常更易于使用,在PHP中可能没有太大区别。
  • 无限存储空间

会话缺点:

  • 更难扩展
  • 在 Web 服务器重启时,您可以根据实现情况丢失所有会话或不丢失。
  • 非RESTful

2
会话优点:安全 - user2167582
1
为什么会话更安全?如果您通过HTTP发送会话cookie,则可能会被劫持。如果网站使用HTTPS安全协议,只要您使用安全cookie(加密、签名等),安全性应该是相同的。 - filippo
1
Cookies的缺点:使每个请求变得更大,可能影响性能。我不知道具体数字,但由于人们使用无cookie域来做一些事情,我认为这是非微不足道的。 - maniexx
23
这个回答大部分是误导性的,session不是cookie。根据服务器上的会话管理实现方式,您可以有会话变量。您通常拥有一个或多个与会话管理相关的cookie,通过保存会话标识符。此外,REST和RESTful与cookie或会话管理无关 - REST和RESTful实现可以具有会话和cookie。 - Zlatin Zlatev
5
我并不是说通常情况下会使用cookie来实现session,而是还有其他选项可用于session管理,因此错误地将session变量称为服务器端cookie。我在上面的评论中提到JWT时,也指出了在2017年时“REST和RESTful实现可以具有会话和cookie”。尽管一些纯粹主义者可能会认为这不是实现REST API的正确方式。 - Zlatin Zlatev
显示剩余9条评论

86

您可能是指Http Only cookie与它们的对应物之间的区别?

Http Only cookie 不能被客户端 JavaScript 访问(读取或写入),只能在服务器端访问。如果未设置 Http Only 标志,或者 cookie 是在(客户端)JavaScript 中创建的,则该 cookie 可以在客户端 JavaScript 和服务器端中读取和写入。


在我看来,这是正确的答案,因为它直击问题的核心,而不会被会话所分散注意力(最受欢迎的答案中对此描述不够明确,并且与此无关,因为你可以有可在客户端读取的会话Cookie和只能通过HTTP访问的会话Cookie)。 - Alex White

61

所有的cookie都是客户端和服务器共用的

没有区别。普通cookie可以在服务器端或客户端设置。 “经典”cookie将随每个请求返回。由服务器设置的cookie将在响应中发送给客户端。只有在显式设置或更改时,服务器才会发送cookie,而客户端会在每个请求上发送cookie。

但从本质上讲,它们是相同的cookie。

不过,行为可能会发生改变

Cookie基本上是一个名称=值对,但值后面可以是一些分号分隔的属性,如果客户端(或服务器)实现了它,则会影响 cookie的行为。这些属性可能涉及生存期、上下文和各种安全设置。

HTTP-only(不仅限于服务器)

其中之一的属性可以由服务器设置,以指示它是一个HTTP-only cookie。这意味着cookie仍然来回发送,但它在JavaScript中不可用。请注意,cookie仍然存在!这只是浏览器内置的保护措施,但是,如果有人使用像IE5这样的过时浏览器或某些自定义客户端,他们实际上可以读取cookie!

因此,似乎存在“服务器cookie”,但实际上并不存在。这些cookie仍然发送到客户端。在客户端上,没有办法阻止cookie被发送到服务器。

实现“仅限”的替代方法

如果您想仅在服务器或仅在客户端存储值,则需要其他一些类型的存储,例如服务器上的文件或数据库,或客户端上的本地存储(Local Storage)。


你好,我对这些概念非常陌生,有一些疑问。很抱歉,我的问题可能听起来很傻,但我仍然会问。任何帮助都将不胜感激 - 客户端设置的 cookie 是否可以发送到任何域?我的意思是,这不是安全威胁吗?另外,它在非浏览器客户端(如 API 等)中如何工作? - Chesser
2
嗨@KaranChadha ,如果你有问题,请使用页面顶部的“提问”按钮以正式问题提出。在一个7年前的问题的评论线可能不会引起足够的关注。当然,添加到该Q&A的链接或甚至是特定答案的链接都是可以的,您可以使用每个帖子底部的“分享”按钮来实现。 - GolezTrol
这是真的吗?客户端生成的 cookie 似乎没有被传输。如果执行 document.cookie="foo=bar",然后跟着 fetch("/foobar", {credentials: 'include'} ),没有包含 foo=bar 的 cookie 被发送。我刚刚在这个网站上使用 DevTools 和控制台直接尝试了一下这段代码。 - oligofren
是的,这是真的,文档也这样说,但有一些细节可能会导致这种情况,比如缺少过期属性。 - GolezTrol
"没有区别":客户端是否可以覆盖服务器设置的cookie? - Marinos An
1
@MarinosAn 是的,它可以。但是,当涉及到修改 cookie 行为的属性时,我的回答有些简略,所以我现在进行了扩展。 - GolezTrol

19
什么是在服务器端和客户端创建cookie的区别?
您所提到的是在客户端设置cookie的两种方式,它们分别是:
- 由服务器设置 - 由客户端(通常是浏览器)设置
由服务器设置:
服务器的Set-cookie响应头指示客户端在该特定域上设置cookie。实际创建和存储cookie的实现位于浏览器中。对于对同一域的后续请求,浏览器会自动设置每个请求的Cookie请求头,从而使服务器能够获取一些状态,而不是无状态的HTTP协议。域和路径cookie属性用于让浏览器确定要发送到服务器的cookie。
服务器只接收名称=值对,而没有其他内容。
由客户端设置:
可以使用document.cookie = cookiename=cookievalue在浏览器上创建cookie。但是,如果服务器不打算响应用户创建的任何随机cookie,则此类cookie没有任何用处。
这些是否称为服务器端cookie和客户端cookie?
Cookie始终属于客户端。没有所谓的服务器端cookie。
是否有一种方法可以创建仅在服务器上可读取的cookie?读取Cookie的值是由服务器和客户端决定的,它取决于是否需要在其中一个位置读取Cookie。 在客户端上,通过设置Cookie的HttpOnly属性,可以防止脚本(主要是Javascript)读取您的Cookie,从而作为防御机制防止通过XSS进行Cookie盗窃,但仅将Cookie发送到预期的服务器。 因此,在大多数情况下,由于Cookie用于带来“状态”(记忆过去用户事件),在客户端创建Cookie并没有太大价值,除非您了解服务器使用/响应的Cookie。 参考:维基百科

3
  1. 是的,你可以创建只能在服务器端读取的cookie。它们被称为“HTTP Only”-cookie,正如其他答案已经解释过的那样。
  2. 不,没有办法(我所知道的)创建只能在客户端读取的“cookies”。Cookies的目的是促进客户端和服务器端之间的通信。
  3. 但是,如果你想要类似“仅限客户端”的cookie,有一个简单的答案:使用“本地存储”。

本地存储实际上比Cookie更容易使用。关于Cookie和本地存储的简明概述,请参阅:

https://courses.cs.washington.edu/courses/cse154/12au/lectures/slides/lecture21-client-storage.shtml#slide8

一点说明:你可能会使用在JavaScript中创建的cookie来存储GUI相关的内容,这些内容只需要在客户端上使用。但是cookie会被发送到每个请求中的服务器,成为http-request headers的一部分,从而使请求包含更多数据,因此发送速度较慢。

如果您的页面具有50个资源,例如图像、CSS文件和脚本,则cookie通常会随每个请求一起发送。有关详细信息,请参阅Does every web request send the browser cookies?

本地存储没有这些与数据传输相关的缺点,它不发送任何数据。它非常好。


没有,据我所知,没有办法创建仅在客户端读取的“cookies”。Cookies旨在促进客户端与服务器之间的通信。那么document.cookie呢?JavaScript可以设置客户端cookie,对吗? - Ishwar Rimal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接