zoukankan      html  css  js  c++  java
  • JavaScript快速入门笔记(13):cookie

    本系列随笔是本人的学习笔记,初学阶段难免会有理解不当之处,错误之处恳请指正。转载请注明出处:https://www.cnblogs.com/itwhite/p/12267738.html

    简介:客户端存储,服务端使用

    cookie 是一种早期的客户端存储机制,最初是针对服务端脚本设计使用的(由服务端发起 Set-Cookie,存储于客户端浏览器中,然后客户端每次发送请求时都带上 cookie 值,服务端通过 cookie 来识别用户)。

    cookie 作为一种被服务端脚本使用的客户端存储机制,其工作过程如下图所示:

    下面以一段简单的 PHP 服务端程序(foo.php)模拟上述过程:

    <?php
      if (!isset($_COOKIE["foo"])) {
        setcookie("foo", "1234", time()+3600); // 服务端调用这个函数,在发送到客户端的响应头部信息中会添加一个 Set-Cookie 字段告诉客户端存储这个 cookie
      }
    ?>

    从浏览器端打开这个页面,并进入开发者模式查看HTTP请求和响应,如下图所示:

    Set-Cookie

    从图中可以看到服务端响应报文头部会包含一个 Set-Cookie 字段(其内容正是我们在服务端程序中设置的),浏览器会自动存储这个 cookie,当我们下一次访问 foo.php 这个页面时,客户端的请求报文头部信息中会带上这个 cookie 发送给服务端,如下图所示:

    Cookie

    客户端(JavaScript)中读写cookie

    前面的示例中,cookie 的读、写都在服务端脚本中完成,实际上客户端脚本中也可以读写 cookie (客户端生成的 cookie 也会在下一次发起请求时发送至服务端)。

    不过 JavaScript 并没有提供很友好的 API 来操作 cookie ,客户端中可以通过 document.cookie 属性(其值是一个字符串)来读写 cookie 。

    示例一:读取 cookie

    还是以前面的 foo.php 为例,在其后面加上客户端脚本,代码如下:

    <?php
      if (!isset($_COOKIE["foo"])) {
        setcookie("foo", "1234", time()+3600);
      }
    ?>
    <script>
      alert(document.cookie);
    </script>
    View Code

    再次访问 foo.php 页面时,浏览器端会在弹出框中输出cookie的内容,如下图所示:

    客户端读取cookie

    示例二:设置 cookie

    直接赋值给 document.cookie,代码如下:

    <script>
      document.cookie = "bar=5678;max-age=3600";
    </script>
    View Code

    注意:上面的代码看起来像是覆盖了 document.cookie 原来的值,实际上不会,此处创建了一个新的 cookie (键名为 bar),原来的 foo 仍然存在,并且打印 document.cookie 时会同时输出 foo=1234; bar=5678 。

    如何禁止客户端读取 cookie ?

    从上面的示例可以看到,JavaScript 脚本也能读写 cookie,但是出于安全性考虑,有时候我们可能不希望通过服务端设置的 cookie 被客户端脚本读写。

    本文第一节的示例中用到 PHP 的 setcookie() 方法中其实还可以传入更多的参数(只不过前面的示例给省略了):

    setcookie(name, value, expire, path, domain, secure, httponly)

    其最后一个参数 httponly 用于控制是否仅可以通过 HTTP 协议访问(默认为 false),若设置为 true 则 JavaScript 脚本就无法访问了,这样可以减少 XSS 攻击时的身份窃取行为,例如(修改 foo.php 代码):

    <?php
      if (!isset($_COOKIE["foo"])) {
        setcookie("foo", "1234", time()+3600, "/", "", false, true);
      }
    ?>

    然后再次访问 foo.php 页面,从开发者工具的 Application 标签的 Cookies 中,我们可以看到 foo 的 HttpOnly 标志已经设置成了 true ,如下图所示:

    HttpOnly设置

    提示:当再次从 JavaScript 中读取 document.cookie 时就只能读到 bar 而不能读到 foo 了,清除某个站点的 cookie 也可以从上图中页面中进行操作 。

    cookie 的有效期

    当设置 cookie 不指定有效期时,其默认有效期为 session ,如下图所示:

    不指定cookie有效期

    这种 cookie 只能存活于 Web 浏览器的会话期间(相对于整个浏览器进程,而不是单个窗口),当重启浏览器后 bar 就不存在了,foo 只要还没过期就仍然存在。

    如果想要延长 cookie 的有效期,就需要明确地指定 cookie 的有效期,方法如下:

    • PHP 的 setcookie() 中第三个参数用于指定有效期,它的值是相对于1970年1月1日开始时的秒数;
    • JavaScript 中使用 max-age 来指定相对于当前时间的最大存活秒数。

    前面示例中都有用到,这里就不重复举例了。

    cookie 的作用域

    cookie 的作用域是通过“文档源”(domain)和“文档路径”(path)来确定的。

    假设我们在设置 cookie 时没有指定 path 和 domain,那么会出现以下情况:

    • 我们在 www.example.com/foo/index.php 中设置的 cookie,在 www.example.com/bar/index.php 中是不可以访问的,因为他们属于不同的路径,如果要想让后者能访问,我们可以将 path 设置成“/”。
    • 我们在 www.example.com/foo/index.php 中设置的 cookie,在 www.example.com/foo/bar/index.php 中是可以访问的,因为后者是前者的子目录,反过来则不可以。
    • 我们在 foo.example.com/index.php 中设置的 cookie,在 bar.example.com/index.php 中是不可以访问的,因为它们属于不同的子域,要想让它们共享,我们可以将 domain 设置为“.example.com”(注意前面的点号)同时将 path 设置为“/”。

      

    完。

  • 相关阅读:
    让CEF支持FLASH(非安装插件的形式)
    解决SQLServer 2008 日志无法收缩,收缩后大小不改变
    HTML Socket实现 .NET
    JS基础之BOM对象
    JavaScript对象
    JS函数
    JavaScript概述
    CSS块级元素和行内元素
    返回顶部示例
    CSS属性操作二
  • 原文地址:https://www.cnblogs.com/itwhite/p/12267738.html
Copyright © 2011-2022 走看看