当我们不使用SSL时,使用ajax的文件上传工作得很好,但当我们使用SSL时就失败了。也就是说,在我们的开发服务器(没有SSL)上,以下操作可以正常工作。在我们使用SSL之前,它在生产环境中也运行得很好。
我们的服务器基础设施(在rackspace)现在在负载均衡器上有SSL终止,以便会话可以与其中一个web服务器挂钩。我们还使用.htaccess来检查{HTTP:X-Forwarded-Proto}并强制使用HTTPS。如果我们删除强制SSL的.htaccess,并使用HTTP发出以下请求,它就可以工作了。将.htaccess放回原位,除了文件上传部分,其他一切都可以正常工作。所有其他ajax调用都很好,表单可以构建,按钮可以工作……
.htaccess文件:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI}
js/widget-groups.js构建了一个模态表单来创建或更新组的详细信息,包括为组徽标上传文件。它基于UserFrosting,表单并不是特别有趣。相关位为:
/* Display a modal form for updating/creating a group */
function groupForm(box_id, group_id) {
group_id = typeof group_id !== 'undefined' ? group_id : "";
// Delete any existing instance of the form with the same name
if($('#' + box_id).length ) {
$('#' + box_id).remove();
}
var data = {
box_id: box_id,
render_mode: 'modal'
};
if (group_id != "") {
console.log("Update mode");
data['group_id'] = group_id;
data['show_dates'] = true;
}
// Generate the form
$.ajax({
type: "GET",
url: "load_form_group.php",
data: data,
dataType: 'json',
cache: false
})
.fail(function(result) {
addAlert("danger", "Oops, looks like our server might have goofed. If you're an admin, please check the PHP error logs.");
alertWidget('display-alerts');
})
.done(function(result) {
// Append the form as a modal dialog to the body
$( "body" ).append(result['data']);
$('#' + box_id).modal('show');
// Link submission buttons
$('#' + box_id + ' form').submit(function(e){
var errorMessages = validateFormFields(box_id);
console.log("in widget Link submission buttons");
var myFileList = document.getElementById('image_url').files;
myFileList = typeof myFileList !== 'undefined' ? myFileList : false;
console.log(myFileList);
/*
var myFile = myFileList[0];
console.log(myFile);
console.log("filename="+myFile.name+",size="+myFile.size+",type="+myFile.type);
*/
if (errorMessages.length > 0) {
$('#' + box_id + ' .dialog-alert').html("");
$.each(errorMessages, function (idx, msg) {
$('#' + box_id + ' .dialog-alert').append("<div class='alert alert-danger'>" + msg + "</div>");
});
} else {
if (group_id != "") {
updateGroup(myFileList,box_id, group_id);
} else {
createGroup(myFileList,box_id);
}
}
e.preventDefault();
});
});
}
当用户点击按钮时,调用updateGroup:
// Update group with specified data from the dialog
function updateGroup(myFileList,dialog_id, group_id) {
var data = {
group_id: group_id,
display_name: $('#' + dialog_id + ' input[name="display_name"]' ).val(),
group_logo: $('#' + dialog_id + ' input[name="group_logo"]' ).val(),
csrf_token: $('#' + dialog_id + ' input[name="csrf_token"]' ).val(),
compAddr1: $('#' + dialog_id + ' input[name="compAddr1"]' ).val(),
compAddr2: $('#' + dialog_id + ' input[name="compAddr2"]' ).val(),
compAddr3: $('#' + dialog_id + ' input[name="compAddr3"]' ).val(),
compCity: $('#' + dialog_id + ' input[name="compCity"]' ).val(),
compSt: $('#' + dialog_id + ' input[name="compSt"]' ).val(),
compZip: $('#' + dialog_id + ' input[name="compZip"]' ).val(),
compCountry: $('#' + dialog_id + ' input[name="compCountry"]' ).val(),
ajaxMode: "true"
}
var url = "update_group.php";
$.ajax({
type: "POST",
url: url,
data: data,
}).done(function(result) {
processJSONResult(result);
saveImageUrl(myFileList,group_id);
window.location.reload();
});
return;
}
,它成功调用saveImageUrl:
function saveImageUrl(myFileList,group) {
if (group==false) return false;
if (myFileList.length!=1) return false;
// Create a temporary formdata object and add the files
myurl="upload.php";
console.log("saveImageUrl. myFileList="+myFileList+". group=" + group + ". myurl=" + myurl);
console.log("myFileList[length]="+myFileList[length]);
console.log("myFileList.length="+myFileList.length);
var data = new FormData();
data.append("group",group);
$.each(myFileList, function(key, value)
{
data.append(key, value);
});
/** alternate
var xhr = new XMLHttpRequest();
xhr.open('POST','upload.php',true);
xhr.onreadystatechange = function() {
console.log("onreadystatechange state="+xhr.readyState);
console.log("onreadystatechange status="+xhr.status);
console.log("onreadystatechange responseText="+xhr.responseText);
};
xhr.send(data);
**/
$.ajax({
url: myurl,
type: 'POST',
data: data,
cache: false,
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function(data)
{
console.log("upload success with data=");
console.log(data);
},
error: function(data)
{
console.log("upload error with data=");
console.log(data);
}
});
console.log("image_url=" + image_url);
}
所有额外的注释都是为了看看发生了什么。
upload.php文件以:
开头和结尾<?php
file_put_contents('uploads/debug.txt','---upload+',FILE_APPEND);
...
echo json_encode(array(
"files" => $files,
"errors" => count($errors),
"successes" => count($successes)));
?>
同样,证据表明file_put_contents在不使用SSL时工作得很好,但在使用SSL时也不会受到影响。使用firebug,控制台显示对upload.php的调用,尽管它总是以红色显示,并且我们最终在error:块中结束,但是"console.log(data)"行没有内容。这可能只是一个问题与返回json,虽然这看起来不错,我。我认为,真正的问题是,它在不使用SSL时成功,但在我们使用SSL时失败。成功时,文件被上传并保存在正确的位置通过update.php.
我不明白SSL的变化是如何影响事情的。其他ajax调用是可以的;只有
这个有问题processData: false, // Don't process the files
contentType: false, // Set content type to false or jQuery will tell the server its a string
我理解这是为了正确处理ajax文件上传所必需的。
是不是还有更多我不明白的事情在发生?
谢谢,Eric
问题的核心是顺序ajax调用。在开发和非ssl生产中,它运行良好。但是,对于SSL,真正的问题浮出水面:时间。
解决方案是添加:
异步:假的,
到ajax调用upload.php。将它添加到第一个ajax请求中没有帮助。只添加到第二个
像许多问题一样,它在最初的帖子中不是很准确,但我发现了很多类似的问题,没有很多令人满意的答案。希望这将是另一个线索,在别人的搜索。
埃里克