Flash消息不可靠,如何解决这种情况?

时间:2014-10-10 20:48:05

标签: php flash-message

几天前没有人回答这个问题,所以我会尝试以不同的方式解释它。这让我无法在我的项目中工作。

在PHP中,您可以在$ _SESSION上存储反馈消息,例如$ _SESSION ['login'] =“failed”,可以在重定向后将其报告给用户。这些被称为flash消息。问题是PHP不知道哪个Flash消息属于哪个浏览器TAB。这是一个例子:

  1. 用户在两个标签上访问website.com/UploadPhoto,并在每个标签上选择一张照片。他几乎在同一时间点击发送。
  2. 第一张照片由表单处理,并成功上传。闪存消息保存为“成功!”,重定向开始回到website.com/myPhotos/,因此用户可以上传更多照片,还可以看到显示的成功flash消息 - 但这里是捕获,用户随机选择AD,他需要10秒才能重定向到他的照片页面。
  3. 第二个图像现在正由表单处理,但它有错误,并收到“错误:文件太大”的flash消息,重定向也会返回到website.com/UploadPhoto

    现在发生的事情是,在第一张图片之后上传的第二张图片首先被重定向并显示一条消息:成功!它劫持了第一个消息,因为它很快就被重定向了。然后,在10 Ad秒之后,图像1的情况被重定向,消息“文件太大”,因为它稍后到达。

    你怎么能阻止这个? 我真的希望有人可以给我一些见解,因为我因为这个而被困在我的项目中

2 个答案:

答案 0 :(得分:1)

当浏览器对某个网址执行请求时,它会发送与域和路径匹配的所有Cookie。无论你进入哪个窗口或标签都没关系,这种行为总是一样的。

您的问题有几个解决方案:

Javascript / ajax

在我看来最简单的方法,因为有很多好的javascript库可以通过XHR(ajax)请求来管理文件上传。我喜欢的是jQuery File Upload

在这种情况下,您不需要flash消息,只需将响应中所需的所有信息都放回XHR请求即可。

为窗口/标签

提供ID

Jens-AndréKoch对这是如何运作给出了一个很好的答案。

单独会话

如果您希望完全支持每个窗口/选项卡的单独会话,则不能依赖存储在cookie中的会话ID。然而,这意味着用户必须登录每个窗口/选项卡。我将详细解释这是如何工作的:

  • 用户访问https://my.domain.com/并提供了一个用于登录的表单。
  • 他/她填写此表单并点击提交按钮。浏览器执行POST请求。
  • 服务器收到此请求,看到输入正确,将登录状态存储在新会话中,并发送包含网址{30}的30x响应
  • 浏览器通过对该网址执行GET请求来响应此响应。
  • 服务器识别URL中的会话ID并恢复该会话,查看登录状态,并发送包含表单的200响应以上载文件。表单元素shoud的action属性包含会话ID(https://my.domain.com/upload/?session_name=session_id)。
  • 用户填写上传表单并点击提交按钮。浏览器执行POST请求。
  • 服务器接收请求并处理文件上载。现在可能发生两件事:
    1. 失败:
      • 服务器发送包含错误消息和原始文件上载表单的200响应。用户可以再试一次。
    2. 成功:
      • 服务器在会话中存储成功的Flash消息,并发送包含网址https://my.domain.com/upload/?session_name=session_id的30x响应。
      • 浏览器通过对该网址执行GET请求来响应此响应。
      • 服务器收到请求,看到会话中有一条flash消息,并发送一个200响应,其中包含flash消息(随后从会话中删除)以及文件上载表单。

您现在应该得到要点:服务器返回的每个网址都必须包含会话ID。您不再依赖cookie中的会话ID(实际上禁止在PHP中发送包含会话ID的cookie)。

我对请求/响应也非常明确,以更好地说明http协议的实际工作方式。

答案 1 :(得分:0)

你的flashmessages不知道,何时以及出于何种原因他们应该展示。 图像上载完成后,您可能会根据图像标识符显示flashmessage。

要获得类似"成功:来自标签A上传的图像1的消息",您需要向会话添加更多数据,例如图像ID以及上传进度的状态。如果你真的需要标签标识符,那么也添加它。

  • $_SESSION['flashmessages']['image_uploads'][$id]['state'] = "uploading";
  • $_SESSION['flashmessages']['image_uploads'][$id]['state'] = "finished";

    if(array_key_exists('image_uploads', $_SESSION['flashmessages']) === true) 
    {
        foreach($_SESSION['flashmessages']['image_uploads'] as $image => $values) {
            if($values['state'] === 'finished') {
               // output flashmessage
               echo 'Success: Image ' . $image . ' was uploaded.';
               // unset this flashmessage
               unset($_SESSION['flashmessages']['image_uploads'][$id]);
            }
        }
    }