Cookie 与基于会话的 Flash 消息

发布于 2024-11-07 17:51:19 字数 471 浏览 1 评论 0原文

我在 CakePHP 中发现的一个巧妙的功能是能够设置 flash 消息,例如在某些 save 脚本上,然后将该消息显示在下一页上。例如,发布更新,或错误 - 未找到文件。

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

干杯!

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

A neat feature which I found in CakePHP was the ability to set a flash message, say on some save script, then have that message displayed on the following page. Something like, Post updated, or Error - no file found.

The way Cake does it is with this session object. I am trying to avoid sessions like the plague because of their odd requirements for scalability. Can I not just simply store the flash message in a cookie (client side) and then delete that cookie once it's displayed on the following page? What would be some pros/cons to this approach - or more simply, why does Cake uses session (I'm assuming that relates to the _SESSION collection).

Cheers!

p.s. In my implementation I also make it fade out with a setTimeout command in javascript. I find that's a nice way to end the whole process.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅笑轻吟梦一曲 2024-11-14 17:51:19

cookie 的问题是用户可能会禁用此功能。如果是这样,您的即时消息将不会显示。 CakePHP 尝试足够通用并使用会话存储。

您有 3 个选项:

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

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

The problem with a cookie is that the user may disable this functionality. If so, your flash message won't be showed. CakePHP try to be general enough and uses session storage.

You have 3 options:

  1. Session: the most used approach. It will work in any client computer but, as you say, it could give problems with some server configurations.
  2. Cookies: it's a good option in general, but the user may block this mechanism. Only recommendable when the your app requirements include the need of cookies.
  3. Data base: the universal solution. The problem is that it requieres an access to the database (slow). An ID should be passed with the URL (GET method) so the application knows which database register corresponds to this access.

In my applications I use a combination of the 2nd and 3rd approaches: I test for cookies and if they are available, I use them. If not, I use database access, BUT I always cache the DB access in order to not query more than once for each message.

梦在深巷 2024-11-14 17:51:19

我不明白为什么你不能使用自创建日期起 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 存储来管理 Flash 消息。

I don't see why you can't use a cookie with an expiration of say 10 minutes from creation date. Downside if the user walks away and comes back in 11 minutes they might not see the flash cookie message...but you won't have to worry about flooding a client with cookies.

Just make some simple content rules to ensure that no privileged information is put into a flash message and you should be good.

A simple implementation could be something procedural like:

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
}

Alternatively if the flash is originating soley from the client side, you can use something like https://github.com/marcuswestin/store.js to try and use localSession store to manage flash messages.

凉栀 2024-11-14 17:51:19

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

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

优点:

  • 无需 cookie/会话/数据库/内存缓存等即可工作。:-)
  • 不像 cookie 那样依赖客户端时钟
  • 没有其他客户端请求可以“窃取”消息

缺点:

Another idea is the transport of the message via the hash in the url:

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

Advantages:

  • Does work without cookies / sessions / databases / memcaches etc. :-)
  • Does not rely on client clock as cookies do
  • No other client request can "steal" the message

Disadvantage:

放血 2024-11-14 17:51:19

不幸的是,当后面跟着 Header("Location ..."); 时,会话并不总是可靠的。

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

编辑:除非 session_write_close();被使用。

Sessions are unfortunately not always reliable when followed by Header("Location ...");

I was thinking of putting it to GET request or Hash tag as was suggested, and you can erase it on next page using javascript from the URL using window.history.pushState.

Edit: Unless session_write_closed(); is used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文