在长时间运行的PHP过程中,Chrome Ajax请求无法正常工作

时间:2013-10-29 21:39:42

标签: php jquery ajax google-chrome

我继承了一个仍然在jQuery 1.2.6上的CakePHP项目。此外,它设置为使用基于文件的会话。请注意,您可能不需要熟悉CakePHP就能够回答这个问题。

我被要求添加一个功能,管理员可以上传CSV联系人,它会遍历CSV行,尝试将该行与已存在于数据库中的联系人匹配。如果找到匹配项,它将使用CSV行中的数据更新任何数据库记录的空白字段。如果找不到匹配 ,则会将新记录添加到数据库中。

CSV预计有~10K行,因此需要一段时间。为了向用户显示导入的进度,我已经有了这个JavaScript:

function get_import_progress() {
    $.ajax({
        url: contact_import_progress_url,
        cache: false, // Internet Explorer
        dataType: 'json',
        success: function(data) {
            var import_progress_details_html;

            if (data.row < data.total_rows) {
                var percentage =
                    Math.round(((data.row / data.total_rows) * 100) * 100) / 100;

                import_progress_details_html =
                    data.row + ' / ' + data.total_rows + ' row(s) ' +
                    'processed (' + percentage + '%)';
            } else {
                window.clearInterval(get_import_progress_interval);

                import_progress_details_html = 'Finalizing... please wait...';
            }

            $('#import_progress_details').html(import_progress_details_html);
        },
        error: function() {
            $('#import_progress_details').html(
                'An unexpected error occurred checking on the progress.'
            );
        }
    });
}

$(document).ready(function() {
    $('#ContactImportForm').submit(function() {
        get_import_progress_interval =
            window.setInterval(get_import_progress, 5000);

        $(this).after(
            '<div class="import_progress"></div>'
        ).next('.import_progress').html(
            'Progress will be shown here and will update every 5 seconds.' +
            '<div id="import_progress_details">Please wait...</div>'
        );
    });
});

当我第一次尝试这个时,我使用的是Firefox 25.0,我发现所有的Ajax请求都悬而未决,大概是因为会话由处理CSV的后端代码使用。这是我用来解决这个问题的相关PHP代码:

$row = 0;

while (($data = fgetcsv($handle, 1000)) !== false) {
    ++$row;

    if ($row > 1) {
        session_start();
    }

    CakeSession::write(
        sprintf(
            'contact_import_progress%s.row',
            $this->request->data['Contact']['form_uuid']
        ),
        $row
    );

    session_write_close();

    ...
}

fclose($handle);

// See https://bugs.php.net/bug.php?id=38104

header(
    sprintf(
        'Set-Cookie: %s=%s; expires=%s; path=%s; HttpOnly',
        Configure::read('Session.cookie'),
        session_id(),
        gmdate(
            'D, d-M-Y h:i:s \G\M\T',
            CakeSession::$sessionTime
        ),
        CakeSession::$path
    ),
    true
);

使用session_write_close()session_start()header(...)代码,Ajax请求开始在Firefox中运行。我测试了Internet Explorer 8,它也在那里工作。然后我在Chrome 30.0.1599.101中进行了测试,发现它无法正常工作。实际上,查看开发人员工具的“网络”部分,似乎甚至根本没有发送Ajax请求!如果我向beforeSend调用添加$.ajax()函数,则会调用该函数,但Ajax请求本身永远不会被发送... 除非我点击Chrome的“停止”按钮。当我这样做时,它的行为与我点击Firefox或Internet Explorer中的“停止”按钮时的行为相同,即:PHP仍在处理CSV,但浏览器没有尝试接收对其请求的响应(表单提交),所以Ajax请求继续(或者,在Chrome的情况下, start )出去并且进度更新(因为PHP仍在处理CSV)。

如何在Chrome中按预期使Ajax请求正常工作?

0 个答案:

没有答案