0

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

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

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

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

    你怎么能防止这种情况发生?我真的希望有人能给我一些见解,因为我因此被困在我的项目中

4

2 回答 2

1

当浏览器对某个 url 执行请求时,它会发送与域和路径匹配的所有 cookie。无论您在哪个窗口或选项卡中,此行为始终相同。

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

Javascript / ajax

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

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

为窗口/选项卡提供一个 ID

Jens-André Koch 对它的工作原理给出了很好的回答。

单独的会话

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

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

您现在应该了解要点:服务器返回的每个 url 都必须包含会话 ID。您不再依赖 cookie 中的会话 id(事实上,在 PHP 中禁用发送包含会话 id 的 cookie 是明智的)。

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

于 2014-10-10T20:54:53.910 回答
0

您的 flashmessages 不知道它们应该显示的时间和原因。图像上传完成后,您可能会根据图像标识符显示 Flash 消息。

要获得类似“成功:来自标签 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]);
            }
        }
    }
    
于 2014-10-11T00:14:10.307 回答