我继承了一个仍然在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请求正常工作?