Cookie 与基于会话的闪存消息


Cookie vs. Session based flash message

我在 CakePHP 中发现的一个简洁的功能是能够设置flash消息,比如在某些save脚本上,然后将该消息显示在下一页上。类似的东西,Post updatedError - no file found.

蛋糕的方式就是用这个session对象。我试图避免像瘟疫这样的会话,因为它们对可扩展性有奇怪的要求。我不能简单地将闪存消息存储在 cookie(客户端)中,然后在该 cookie 显示在下一页上后将其删除吗?这种方法的一些优点/缺点是什么 - 或者更简单地说,为什么 Cake 使用session(我假设这与_SESSION集合有关)。

干杯!

附言在我的实现中,我还在javascript中使用setTimeout命令使其淡出。我发现这是结束整个过程的好方法。

cookie 的问题在于用户可能会禁用此功能。如果是这样,您的 Flash 消息将不会显示。CakePHP 尽量足够通用并使用会话存储。

您有 3 个选项:

  1. 会话:最常用的方法。它可以在任何客户端计算机上运行,但正如您所说,它可能会给某些服务器配置带来问题。
  2. Cookie:一般来说,这是一个不错的选择,但用户可能会阻止这种机制。仅当您的应用要求包括需要 Cookie 时,才推荐使用。
  3. 数据库:通用解决方案。问题是它需要访问数据库(慢)。ID 应与 URL(GET 方法)一起传递,以便应用程序知道哪个数据库寄存器对应于此访问。

在我的应用程序中,我使用第二种和第三种方法的组合:我测试 cookie,如果它们可用,我就使用它们。如果没有,我使用数据库访问,但我总是缓存数据库访问,以便不会对每条消息进行多次查询。

我不明白为什么你不能使用自创建日期起 10 分钟过期的 cookie。 如果用户离开并在 11 分钟内回来,他们可能不会看到 flash cookie 消息,则不利之处......但是您不必担心用 cookie 淹没客户端。

只需制定一些简单的内容规则,以确保没有特权信息放入闪存消息中,您应该很好。

一个简单的实现可以是这样的过程:

function setFlash($id ,$message){
   setcookie("flash_{$id}", $message, time() + 60 * 10);
}

function getFlashes(){
   $flashes = array();
   foreach($_COOKIE as $id => $value){
        if(strpos($id, "flash_") === 0){
             $flashes[$id] = $value;
             //clear flash and set expiration to 10 minutes in past
             setcookie($id, "", time() * 60 * -10);
         }
  }
  return $flashes;
   //Input cleansing not included for brevity/clarity
}

或者,如果闪存来自客户端,则可以使用类似 https://github.com/marcuswestin/store.js 的内容来尝试使用localSession存储来管理闪存消息。

另一个想法是通过 url 中的哈希传输消息:

if (isset($_POST['submit'])) {
    ...
    header("Location: ".$_SERVER["REQUEST_URI"]."#".urlencode($msg));
    ...
}

优势:

  • 在没有cookie/会话/数据库/内存缓存等的情况下工作:-)
  • 不像 cookie 那样依赖客户端时钟
  • 没有其他客户端请求可以"窃取"消息

缺点:

  • 看起来很丑
  • 最大安全 URL 长度为
  • 2000 个字符(请参阅不同浏览器中 URL 的最大长度是多少?
  • 需要客户端 JavaScript 来读取和显示哈希值
  • 如果已添加书签:每次都会再次显示消息

不幸的是,会话在后面跟标题("位置...")时并不总是可靠的;

我正在考虑按照建议将其放入GET请求或哈希标签中,您可以使用javascript使用window.history.pushState从URL中删除它。

编辑:除非使用session_write_closed();。