PHP,AJAX:大数据被截断

9

问题

我正在使用jQuery将(相对较大的)数据发送到一个Web系统,我正在从Ubuntu迁移到CentOS(这是一个痛苦的过程)。问题在于接收到的数据被截断了。从服务器发送相同的数据到客户端不会出现截断。

被“发送”的数据量(即调试JavaScript时看到的数据量)为116,902字节(正确的数据量),而接收到的数据量大约为115,668字节:这个数字似乎有所变化,这让我相信问题可能与时间有关。事务完成(接收、响应)大约需要3.1秒,这并不是很长的时间。是否有任何设置我应该检查?

除此想法外,我的PHP安装已配置为接受8M的post数据并使用128M的物理内存,这似乎足够了。

以下是jQuery代码。我非常确定这不是问题,但我已按要求包含了它。

接收:

function synchronise_down()
{
    $.ajax({url: "scripts/get_data.php",
        context: document.body,
        dataType: "json",
        type: "POST",
        success: function(result)
            {
                // Fix the state up.
                update_data(result);

                // Execute on syncronise.
                execute_on_synchronise();
            },
        error: function(what, huh)
            {
                IS_WAITING = false;
            }
        });
}

发送中:

function synchronise_up()
{
    var serialised = MIRM_MODEL.serialise();
    LAST_SERIALISED = new Date().getTime();
    $.ajax({url: "scripts/save_model.php",
        context: document.body,
        dataType: "json",
        data: {"model":serialised},
        type: "POST",
        success: function(result)
            {
                // Fix the state up.
                update_data(result, true);

                // Execute on syncronise.
                execute_on_synchronise();
            },
        error: function(what, huh)
            {
                IS_WAITING = false;
            }
        });
}

解决方法(不算是完美解决方案)

编辑:我已经“修复”了这个问题,但并没有找到问题所在以及如何解决它。这是一个有趣的问题,所以我将描述一下我的解决方法并保留此问题。

我的做法是,不让jQuery直接处理大数据的序列化,而是自己先处理好数据,实质上进行了两次序列化。具体代码如下:

function synchronise_up()
{
    var serialised = JSON.stringify(MIRM_MODEL.serialise());
    LAST_SERIALISED = new Date().getTime();
    $.ajax({url: "scripts/save_model.php",
        context: document.body,
        dataType: "json",
        data: {"model":serialised},
        type: "POST",
        success: function(result)
            {
                // Fix the state up.
                update_data(result, true);

                // Execute on syncronise.
                execute_on_synchronise();
            },
        error: function(what, huh)
            {
                IS_WAITING = false;
            }
        });
}

重要的一行是:

var serialised = JSON.stringify(MIRM_MODEL.serialise());

现在,当它到达服务器时,我需要解码这些数据,因为它已经被序列化两次。这种“解决方案”会增加一些成本:发送更多的数据,执行更多的工作。问题仍然存在:什么是问题,以及真正的解决方案是什么?


当您检查实际数据时,能否看到截断? - Madara's Ghost
@Truth 是的,截断是可见的。有问题的数据在接收后被插入到数据库中,检查数据库显示数据有误。此外,从客户端从服务器检索数据也显示相同的问题。 - Liam M
@ajreal 我已经将它添加到我的原始帖子中。我非常确定这很好(它已经运行了几个月了),但你询问了,所以在这里。其中有一些未解释的部分,但所有这些都是正常工作的。 - Liam M
有人对这个问题有了解吗?我也遇到了同样的问题。 - icy
8年后,我认为你将把它迁回Ubuntu,因为Redhat的掌权者已决定我们必须为centos支付费用,否则我们将成为他们的测试点。不幸的是,这是一个非常合理的计划更改 - 我们确实很长时间以来一直在逃脱。问题很可能是您的max_input_vars,我无法通过.htaccess设置它,因为它不能通过ini_set设置。仍然在尝试中。 - Ajowi
显示剩余4条评论
4个回答

4

请检查以下php.ini变量:

post_max_size

max_input_vars - 这可能是罪魁祸首,因为它截断了数据。


2
尝试将jQuery的ajax timeout参数设置为较高的数字(注意,它是以毫秒为单位的,因此您可能需要设置10000,即10秒)。 尝试其他选项: 1. 检查您的PHP最大执行时间是否足够。我怀疑这与问题有关,但这是可能的。 2. 在jQuery的错误函数中,对XHR结果运行console.log(xhr)(您必须在Chrome中执行此操作或找到另一种查看结果的方法)。 XHR是一个XHR对象,它包含有关连接发生了什么的调试信息,例如状态代码、超时信息等。

编辑:您是否检查了数据库中字段的最大大小?很可能数据库正在自动截断信息。


谢谢你的建议,我下周会试一试。不过现在正要赶机场,我可以确定的是这个问题不是数据库引起的,因为我正在使用一个长文本列,并且那里没有存储问题。 - Liam M
好的,我已经检查过了,这不是超时问题:故障发生在3秒内,我的超时时间都比那高得多。 - Liam M

1

我的直觉是这可能是一个与 PHP 超时相关的问题,我从没听说过 JavaScript 超时的情况 - 我已经运行了 3 或 4 个小时的 jQuery,但接着他们会发布一些小更新(就像 PHP 中的 _SESSION 进度条...但我跑题了...无论如何,你必须使用 Firefox,IE 不会相信你知道你在做什么并且在大约 40 分钟后超时)〜当时我没有使用 Chrome。

实际上,现在想起来,你说你正在迁移到 CentOS,对我来说听起来像是服务器相关的问题。你只是在错误的地方寻找。

BTW 恭喜你选择 CentOS,它真的很棒!我建议使用简单的方式为此应用程序创建一个完整的 LAMP CentOS VM(不要为此烦恼虚拟主机,非常混乱),并将整个 Apache/PHP 安装设置得非常高。

正确的 php.ini 设置如下:

max_input_time //(not max_execution_time!)
upload_max_filesize
post_max_size
// .. and try    
memory_limit

谢谢Conners,我今天下午刚从旅行回来,所以明天早上我会检查一下。我认为你可能是对的,最大输入时间看起来非常有趣,我很想知道它的价值是多少。顺便说一句,CentOS真是个大麻烦——因为可用的软件包都太老了,而且构建/查找它们的不便根本不值得我的时间,所以我不得不改用Ubuntu。 Ubuntu赢了:)。 - Liam M
<3 Cent OS :D 很抱歉你正在苦苦挣扎(事实上,今天早上我正在使用大约4个CentOS虚拟机进行全新的主机设置 ~:D)如果你需要任何帮助,请给我发电子邮件。 - conners
好的,我已经检查过了,但没有任何进展。我的最长执行时间是60秒,而失败发生在大约3秒内。PS,CentOS有它的优点,但软件包实在是太老旧了,对我来说没有用处。谢谢你的提议:)。 - Liam M
那些值:无论如何都要升高它们..让它们达到最大值..有各种各样的帖子大小限制和其他限制..其中一件事情是必须彻底,你可能需要咬紧牙关并进入细节模式:也就是说,你必须进入Ubuntu并记录下这些分数(对于上述参数),然后应用它们,如果失败了,则逐行检查httpd.conf/php.ini,记住版本跨度可能会很大,并确保每个属性。 - conners
(包括任何vhost.conf和.htaccess属性 - 越来越多的设置在这里进行)这是一个巨大的痛点,但我百分之百确定这是服务器问题,我会拿我的(微薄的)声誉来打赌。我曾经为一所大学工作,用jQuery/PHP编写了整个AD帐户创建脚本,在学生注册期间每天运行8小时(创建打印帐户、文件夹、图书馆登录、电子邮件帐户、学生记录系统项目、moodle信息)。 - conners
每个循环中都有成千上万的任务,成千上万的学生到达,我所见过的唯一客户端超时是IE运行>40分钟时。FF没有这样做,它保持运行状态。 - conners

0

PHP的POST/GET/COOKIE默认限制为1000个条目。超过这个数量的数据将被忽略。计算的是条目数,而不是实际数据量。

我建议您编辑php.ini文件,并将max_input_vars设置为更大的值。

祝好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接