简体   繁体   English

Cookie与基于会话的Flash消息

[英]Cookie vs. Session based flash message

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. 我在CakePHP中找到的一个简洁的功能是能够设置一个flash消息,比如在一些save脚本上,然后在下一页显示该消息。 Something like, Post updated , or Error - no file found. Post updatedPost updatedError - no file found.

The way Cake does it is with this session object. Cake执行此操作的方式是使用此session对象。 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? 我是否可以简单地将Flash消息存储在cookie(客户端)中,然后在下一页显示后删除该cookie? 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). 这种方法的优点/缺点是什么 - 或者更简单地说,为什么Cake使用session (我假设它与_SESSION集合有关)。

Cheers! 干杯!

ps In my implementation I also make it fade out with a setTimeout command in javascript. ps在我的实现中,我也使用javascript中的setTimeout命令淡出。 I find that's a nice way to end the whole process. 我发现这是结束整个过程的好方法。

I don't see why you can't use a cookie with an expiration of say 10 minutes from creation date. 我不明白为什么你不能使用一个在创建之日起10分钟到期的cookie。 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. 如果用户离开并在11分钟后回来,他们可能看不到闪存cookie消息......但你不必担心用cookie充斥客户端。

Just make some simple content rules to ensure that no privileged information is put into a flash message and you should be good. 只需制作一些简单的内容规则,以确保没有特权信息放入Flash消息中,您应该做得很好。

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. 或者,如果闪存源自客户端,则可以使用https://github.com/marcuswestin/store.js之类的东西来尝试使用localSession存储来管理闪存消息。

The problem with a cookie is that the user may disable this functionality. Cookie的问题在于用户可能会禁用此功能。 If so, your flash message won't be showed. 如果是这样,您的Flash消息将不会显示。 CakePHP try to be general enough and uses session storage. CakePHP尝试足够通用并使用会话存储。

You have 3 options: 你有3个选择:

  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. Cookies :一般来说这是一个很好的选择,但用户可能会阻止这种机制。 Only recommendable when the your app requirements include the need of cookies. 仅在您的应用程序要求包含Cookie需要时才推荐。
  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. 应使用URL(GET方法)传递ID,以便应用程序知道哪个数据库寄存器对应于此访问。

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. 在我的应用程序中,我使用第二种和第三种方法的组合:我测试cookie,如果它们可用,我使用它们。 If not, I use database access, BUT I always cache the DB access in order to not query more than once for each message. 如果没有,我使用数据库访问,但我总是缓存数据库访问,以便不为每条消息多次查询。

Another idea is the transport of the message via the hash in the url: 另一个想法是通过url中的哈希传输消息:

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

Advantages: 好处:

  • Does work without cookies / sessions / databases / memcaches etc. :-) 没有cookie /会话/数据库/ memcaches等工作:-)
  • Does not rely on client clock as cookies do 不像cookie那样依赖客户端时钟
  • No other client request can "steal" the message 没有其他客户端请求可以“窃取”该消息

Disadvantage: 坏处:

Sessions are unfortunately not always reliable when followed by Header("Location ..."); 遗憾的是,在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. 我正在考虑按照建议把它放到GET请求或Hash标签上,你可以使用window.history.pushState使用URL中的javascript在下一页上删除它。

Edit: Unless session_write_closed(); 编辑:除非session_write_closed(); is used. 用来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM