【问题标题】:$_POST persistency using an AJAX call使用 AJAX 调用的 $_POST 持久性
【发布时间】:2012-12-11 00:13:49
【问题描述】:

我正在尝试建立一个评论系统,当用户发送评论时,它会显示在他们的屏幕上,就好像它已经存储在数据库中一样。 我的问题是:如果用户发送 cmets 然后导航离开会发生什么 (或者最具体地说是立即关闭窗口)或者他们在 ajax 发布后失去连接?

在代码方面我有ajax({})...

然后我的代码从 textarea 获取用户输入并将其添加到 div。

这意味着用户可以立即看到他们输入的评论。但我想确定即使连接丢失、窗口关闭或用户导航离开,服务器是否也会获取发布信息。


有关问题的更多信息:

用户向服务器发送一个包含 1mb 值的帖子,然后在一毫秒后立即发送 他/她点击了关闭浏览器窗口的按钮。

服务器是否接收并解析带有ignore_user_abort(true);的响应 在文件里面;帖子信息收到了吗?

对于这种情况,如果它是 get 而不是 post 有什么区别?

假设website.com?myget=value

尝试连接然后立即关闭窗口,例如在浏览器窗口中, 只需在地址栏上点击它,然后立即关闭,想象一下 是自动的。

第 1 步转到website.com?myget=value(根本不等待任何服务器响应,只需 立即(一毫秒或脚本执行此操作所需的任何时间)完全关闭 窗户。

$_GET['myget'] 是否会在 website.com 的 index.php 被服务器端接收?

【问题讨论】:

  • 你需要减少重复的句子,兄弟。我很不理解你写的东西。
  • 至少对于ignore_user_abort在尝试向客户端发送信息之前,PHP 不会检测到用户已中止连接。在进行任何回显/打印之前保存您的数据。
  • @SalmanA ignore_user_abort 如果您尝试输出任何内容,将导致脚本不会死掉。因此,如果调用 ignore_user_abort(TRUE),则不需要此建议。

标签: php jquery ajax post response


【解决方案1】:

在大多数情况下,您对服务器执行的任何操作都将继续执行,直到服务器上运行的 PHP 尝试将结果输出回浏览器。只有在这一点上,PHP 才会检查连接是否仍然存在,并根据用户中止设置做任何应该做的事情。因此,例如,如果您想接收帖子、更新数据库条目,然后回显某种成功消息,那么只要您在查询数据库之前没有进行任何输出,数据库活动就应该继续。

POST 与 GET 在这种行为上没有区别。

【讨论】:

  • 但是连接是否真的通过使用 ajax({}) 来“建立”,我真的不需要客户端服务器之间的连接,只是为了服务器接收 $_POST 无论如何如果我用数据写了ajax。想知道在非常慢的连接客户端上的大字符串(假设 500 kb)是否真的会通过说明发布到服务器的操作来到达服务器。服务器会接收还是完全依赖于客户端,除了它只是发送请求。
  • @lbennet 对于大型 POST,客户端需要一段时间才能通过网络发送请求,因此如果用户关闭浏览器或断电或类似情况,他们当然可能没有完成了整个 TCP 通信。服务器处理的方式可能会有所不同。我认为在大多数情况下服务器会丢弃请求。
  • 好的,但是执行一个脚本去 site.com?myget=value 并关闭而不等待任何服务器输出对于 site.com 收到 $_GET 来说已经足够了基本示例,我根本不假设超过 10 kb cmets,问题是如果服务器仅接收请求还不够,或者在继续使用更多 js 之前没有触发异步 ajax 调用代码。我担心的是post没有收到,刚刚收到,但是如果执行查询,则启动XMLHttpRequest - 这对服务器来说足够了吗?
【解决方案2】:

这是一个用户体验问题,而不是技术问题。您要做的是仅在存储新评论后才显示新评论。工作流程应该是这样的:

  1. 用户类型消息
  2. 用户点击“提交”按钮
  3. 系统显示“提交”按钮并显示一条消息,内容如下: “正在发布...”
  4. 当系统可以确认消息已成功发送时 存储后,系统将删除“正在发布...”文本并显示实际新的 消息。

这样用户就知道在请求完成之前不要关闭浏览器或导航离开。


或者,您可以onbeforeunload 警告您的用户在关闭浏览器或导航之前等待。工作流程类似于:

先决条件:您在某处有一个持久计数器(cookie、本地存储、隐藏字段等)。当页面加载时,它从 0 开始。

  1. 用户类型消息
  2. 用户点击“提交”按钮
  3. AJAX 请求已发送
  4. 计数器增加 1
  5. 请求完成,您得到响应(无论成功与否 - 错误处理是另一个问题),将计数器减少 1

如果在任何时候触发了unload 事件,系统将检查计数器。如果大于 0,则警告用户他们的请求尚未完成,他们可能会丢失评论 (a-la-Gmail)。

【讨论】:

  • 不错,不过我想在这个上实现一个快看的效果。
  • 然后我预见到另一个问题。请求完成的速度因请求而异。如果用户开始快速射击 cmets 怎么办?评论 1、2、3、4 可能会以 3、1、4、2 的顺序存储。这个问题并非不可能解决,但如果您要允许用户异步并行添加内容,需要注意这一点。
  • true,至少必须考虑时间戳,使它们成为客户端并在帖子中发送这些,而不是为数据库生成,因为是的,这可能会发生。
  • 不要相信客户端时间。电脑时间设置错误,时区不同等。通常最好只有一个稳定的“时间给予者”(这是我的超级技术术语)。
【解决方案3】:

将添加我的五美分。使用ajax({}),您将要求浏览器开始与您的服务器通信。它需要一些时间来建立连接(ping 时间)并将数据发送到服务器。这两部分都需要一些时间才能完成。为了让 PHP 开始执行,浏览器必须发送它必须发送的所有数据。无论是 POST 还是 GET。如果用户中断发送过程(浏览器崩溃、标签关闭、计算机关闭),PHP 甚至都不会启动。例如,您可以尝试发送一些大文件并使用调试器查看 PHP 脚本何时启动 - 仅在文件完全交付后(您甚至可以在文件上传之前关闭浏览器并查看您的脚本是否已执行) .仅在将所有数据传递到服务器后才开始执行 PHP 并忽略在数据传递之前断开的连接是有意义的。否则可能会出现数据损坏的问题。没有人想要那样。另外,假设 PHP 在所有内容交付到服务器之前启动:您永远无法确定 $_POST["something"] 不可用,因为用户从未输入过它,或者它的数据尚未交付。

如果您使用常规表单提交或 XMLHTTPRequest,则没有区别。在这两种情况下,浏览器都需要一些时间来建立与服务器的连接并将数据传递给它。

【讨论】:

    猜你喜欢
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多