jQuery post 请求中断:只有一半的 post 参数到达

2022-08-30 17:13:00

我注意到我的LAMP环境中有一个奇怪的现象。
在前端,我使用jQuery执行AJAX post请求,如下所示:

$.post('save.php', {data1: d1, data2: d2, [...],  dataN: dN})

要事先使用jQuery从网站收集的变量(例如,从文本输入,文本区域,复选框等) 中收集。d1dN

该文件将 post 参数获取到,并通过一个查询将它们保存在数据库中。save.phpdata1dataN

请求大约需要500毫秒,并且工作没有问题,除非我在请求期间更改页面(例如通过单击链接)。

通常,我希望请求被中止和忽略(这很好),但是(这是奇怪的行为)请求似乎已完成,但只有部分数据传输并因此保存。

这意味着,例如,php 脚本仅保存到 并设置为空。
这个问题似乎是由AJAX请求(不是php脚本)引起的,因为在这种情况下,php中没有设置字段。data1data5data6dataN$_POST['data6']$_POST['dataN']

所以我的问题:
为什么会发生这种情况(这是预期的行为)?
我该如何避免?

更新
问题既不是jQuery,也不是php。jQuery正确收集值并尝试将它们发布到php。我刚刚验证了它 - 它的工作原理。另一方面,php脚本按预期处理它得到的一切 - 它只是没有收到整个请求。
因此,问题一定是中断的请求本身。与我希望它不会中止或失败不同,它仍然传输所有数据,直到截止。
然后php获取此帖子数据并开始处理它 - 显然缺少一些信息。

更新2
我通过在之后添加一个参数并检查它是否在php中设置来修复问题。通过这种方式,我可以确定整个请求已传输。
然而,这并不能解决我仍然不理解的问题的根源。
对任何人有任何帮助吗?eofdataN


答案 1

请尝试以下操作来调试问题:

  1. 检查您的php设置,并将其与您发布的数据大小进行比较。post_max_size

  2. 用户HTTP请求构建器,即用于发出http请求并检查它返回的内容。Fiddler

  3. 在 的顶部使用,检查您正在从中得到什么。print_r($_POST);save.php

  4. 使用工具喜欢检查已发布的内容。FirebugjQuery

  5. 您还应该验证要发布的客户端上的 json 对象。即JSON.stringify(some_object);

  6. 尝试发布一些基本示例数据{ "data1":1, "data2":2, "data3":3, "data4":4, "data5":5 , "data6":6 }

最有可能的是,您正在发送大量数据,或者可能的数据无效!

编辑:非常愚蠢的行为,但让我们说你也发布了计数。所以直接检查 isset($_POST['data'.$_POST['count']] )


答案 2

我认为我们可以排除服务器站点的问题(除非它是一些异国情调或自己制作的服务器守护进程),因为没有人会发送“数据结束”参数并请求确保所有数据都真正发送。这是由自己处理的(例如,请参阅检测HTTP请求正文的结束)。此外,我不认为在将数据传输到服务器时必须检查标头,仅仅是因为没有人这样做。至少在完全常见的情况下,就像您描述的那样(通过发送)。HTTP POSTHTTPContent-LengthPOSTAjaxPOSTjQuery

所以我想这发送了一个语法上正确的,但它被切断了。我的猜测是,如果您通过导航到另一个页面来中断此数据收集,则会从它能够收集的数据中构建一个请求,并将语法正确的内容发送到您的服务器,但要使用切断的数据。jQueryPOSTjQueryAjaxPOST

由于您正在使用 ,请转到其选项卡并激活 ,以便在导航到另一个页面时不会丢失流量数据。然后触发 ,导航到另一个页面(从而“中断”调用),并通过打开所有请求并选中选项卡(以及在此选项卡内部)来检查的网络选项卡中实际发送到服务器的数据。FirebugnetpersistAjax POSTAjaxFirebugPOSTHeadersRequest Headers

我的猜测是,可能会发生以下两种情况之一:

  1. 您将看到发送到服务器的数据已经在 的选项卡中呈现给您的标头中被切断,并且根据数据的实际(截止)长度正确计算。否则,我确信服务器会拒绝整个请求。FirebugnetContent-LengthPOSTBad Request
  2. 你会看到有多个请求,其中一些(可能是完整的,非切断的数据)实际上中断了,因此从未到达服务器,但至少有一个请求(再次,使用截止数据)是由你的其他机制触发的,即不是你认为的触发器,而是通过导航到另一个页面, 可能会触发更多和其他请求(只是一个猜测,因为我不知道你的源代码)。POSTPOSTJavascriptAjax

无论哪种情况,我认为您都会发现这个问题与客户端相关,服务器只是处理客户端发送给它的(不完整的,但(就)语法上有效的)数据。HTTP

从那时起,您可以调试并实现一些机制,以防止向服务器发送不完整的数据。同样,很难确切地说该怎么做,因为我不知道你的源代码的其余部分,但也许在收集数据时会有一些繁重的行动,你可以确保如果所有数据都被真正收集,那么唯一会发生。或者,也许您可以阻止导航,直到请求完成或类似的事情。JavascriptPOSTAjax

如果所有这些都没有意义,那么可能有趣的是,看看你的源代码,特别是它是如何触发的,以及是否有任何其他事件,如果你导航到另一个页面。您发送的示例数据也可能很有趣。Ajax POST

编辑:我还想指出,输出数据可能会产生误导,因为它不能保证这是实际发送的数据,它只是一个logline,它在调用的确切时间计算给定输出。这就是为什么我建议嗅探网络流量,因为那时(只有这样)你才能确定真正发送(和接收)的内容。尽管如此,如果您不习惯它,这有点棘手(如果您使用加密流量(例如通过使用),则不可能,因此该选项卡可能是一个很好的折衷方案。console.log()console.log()HTTPSFirebugnet


推荐