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

Hor*_*ren 25 php mysql ajax jquery post

我在LAMP环境中发现了一个奇怪的现象.
在前端,我用jQuery执行一个AJAX post请求,如下所示:

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

的变量d1,以dN从网站(例如,从文字输入,文字区域,复选框等)与jQuery预先收集.

该文件save.php将post参数data1传递给dataN一个查询并将其保存在数据库中.

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

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

这意味着,例如,PHP脚本只保存data1data5并设置data6dataN空.
这个问题似乎已经被AJAX请求(不是PHP脚本),因为场引起$_POST['data6'],以$_POST['dataN']在PHP中没有设置在这种情况下.

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

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

更新2
我加入一个参数固定的问题eofdataN,并检查它是否是PHP设置.通过这种方式,我可以确保传输了整个请求.
然而,这并不能解决我仍然不理解的问题的根源.
有人帮忙吗?

Waq*_*gir 5

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

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

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

  3. 使用print_r($_POST);在顶部save.php,检查你在里面得到了什么.

  4. 使用工具Firebug来检查jQuery发布的内容.

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

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

很可能你发送的数据很多,或者数据可能无效!

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


ste*_*f77 5

我认为我们可以排除服务器站点上的问题(除非它是一个奇特的或手工制作的服务器守护程序),因为没有人会发送带有HTTP POST确保所有数据都已发送的请求的“数据结束”参数。这是由HTTP它自己处理的(例如,参见HTTP请求主体的检测端)。而且,我认为Content-LengthPOST向服务器输入数据时不必检查标头,仅仅是因为从来没有人这样做过。至少在您描述它们的完全普通情况下(Ajax POST通过发送jQuery)。

因此,我认为该命令jQuery在语法上正确无误POST,但已被切断。我的猜测是,如果您通过导航到另一个页面来中断此数据收集,jQuery则会Ajax从它能够收集的数据中构建一个请求,并将语法正确的发送POST给服务器,但会切断数据。

由于您正在使用Firebug,请转到其net选项卡并激活persist,因此导航到另一页面时不会丢失路况数据。然后触发Ajax POST,导航到另一个页面(从而“中断”的Ajax呼叫)和检查Firebug的净标签实际上是由开放向服务器发送什么数据所有POST请求,检查Headers标签(和这里面的Request Headers选项卡) 。

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

  1. 您会看到在Firebugnet标签中显示给您的标头中已经切断了发送到服务器的数据,并且已Content-Length根据数据的实际(截断)长度正确计算了POST。否则,我确定服务器将整体拒绝该请求Bad Request
  2. 您将看到有多个POST请求,其中一些请求(可能带有完整的非中断数据)实际上已中断,因此从未到达服务器,但是至少有一个POSTist触发了请求(同样具有中断数据)通过您的某种其他机制Javascript(即不是您认为的触发器),而是通过导航到另一个页面,Ajax可能会触发更多和其他请求(这是一个猜测,因为我不知道您的源代码)。

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

从那时起,您可以调试您的代码Javascript并实现某种机制,以防止向服务器发送不完整的数据。同样,由于我不知道其余的源代码,很难说出确切的操作方法,但是也许在收集数据时正在进行一些繁重的操作,并且您可以确保POST只有在所有数据都存在的情况下才会发生真的被收集了。或者,也许您可​​以阻止导航,直到Ajax请求完成或类似的事情为止。

如果所有这些都没有意义,那么可能会感兴趣的是看一下您的更多源代码,尤其是如何Ajax POST触发源代码以及是否有任何其他事件,例如导航到另一个页面。您发送的样本数据也可能很有趣。

编辑:我还想指出,输出数据console.log()可能会误导人,因为它不能保证这是实际发送的数据,它只是一条日志行,它在console.log()调用时准确地评估给定的输出。这就是为什么我建议嗅探网络流量的原因,因为这样(只有这样),您才能确定真正发送(和接收)了什么。尽管如此,如果您不习惯这种方法就比较棘手(如果使用加密的流量,例如使用,则不可能HTTPS),因此该Firebug net选项卡可能是一个不错的折衷方案。


Len*_*Art 1

为了了解更多有关正在发生的事情的信息,为什么不使用 jQuery 的 ajax 函数正确编码您的 ajax 请求。使用所有回调函数来跟踪您的呼叫发生了什么或返回了什么?该元素type设置为 POST,并且该元素data带有您喜欢的任何对象结构{ ... }

$.ajax({
    url : "save.php",
    type : "POST",
    data : {
        "ajax_call" : "SOME_CUSTOM_AJAX_REQUEST_REFERENCE",
        "data1" : data1,
        "data2" : data2,
        "data2" : data2,
        "dataN" : dataN
    },
    //dataType : "html", contentType: "text/html; charset=utf-8",
    dataType : "json", contentType: "application/json; charset=utf-8",
    beforeSend: function () {
        //alert('before send...');
    },
    dataFilter: function () {
        //alert('data filter...');
    },
    success: function(data, textStatus, jqXHR) {
        //alert('success...');
        var response = JSON.parse(jqXHR.responseText, true);
        if (undefined != response.data) {
            my_error_function();
        }
        my_response_function(response.data);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        //alert('error...');            
    },
    complete: function (xhr, status) {
        //alert('end of call...');          
        my_continuation_function();
    }
});
Run Code Online (Sandbox Code Playgroud)