У меня есть веб-форма, которая позволяет пользователю выбрать до 4 файлов для отправки на наш сервер.
При отправке проверка jQuery (v1.14.0) проверяет только наличие файла и его размер менее 3 МБ - она не проверяет, превышает ли размер файла 0 байт (* Первая ошибка *).
Следовательно, если пользователь должен загрузить файл размером 0 байт, данные пройдут проверку внешнего интерфейса и перейдут к сценарию PHP.
Однако маловероятно, что пользователь действительно пытался загрузить файл размером 0 байт. Например, вот содержимое $ _FILE недавней отправки пользователя до любой обработки PHP:
{
"fileOne-0": {
"name": "DOC250618-25062018100132.pdf",
"type": "application/pdf",
"tmp_name": "/tmp/phpZxLpb5",
"error": 0,
"size": 749634
},
"fileTwo-0": {
"name": "Emirates ID.pdf",
"type": "application/pdf",
"tmp_name": "/tmp/phpHHha5Y",
"error": 0,
"size": 0
}
}
Как видите, по какой-то причине размер файла "fileTwo-0" составляет 0 байт.
Затем этот пользователь снова нажал «отправить» менее чем через 20 секунд, и в этот момент и "fileOne-0", и "fileTwo-0" показывают размер 0 байт:
{
"fileOne-0": {
"name": "DOC250618-25062018100132.pdf",
"type": "application/pdf",
"tmp_name": "/tmp/php425HN3",
"error": 0,
"size": 0
},
"fileTwo-0": {
"name": "Emirates ID.pdf",
"type": "application/pdf",
"tmp_name": "/tmp/phpjdaDHO",
"error": 0,
"size": 0
}
}
Следовательно, я предполагаю, что независимо от того, какая ошибка с нашей стороны не проверяет размер файла больше 0, между браузером и кодом JS должно происходить что-то, что влияет на вычисленный размер файла, который пользователь загружается.
Вот код проверки jQuery для формы:
$.validator.addMethod("emailRule", function (value, element) {
return /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(value);
}, "- Your Email address is not in the correct format");
$.validator.addMethod('filesize', function (value, element, param) {
return this.optional(element) || (element.files[0].size <= param)
});
$("#form").validate({
focusInvalid: false,
errorContainer: "#validation-results",
errorLabelContainer: "#validation-results",
errorElement: "li",
onfocusout: false,
onkeyup: false,
groups: {
fileGroup: "fileOne fileTwo fileThree fileFour"
},
rules: {
fullName: {
required: true,
maxlength: 50
},
emailAdd: {
emailRule: true,
maxlength: 80,
required: true
},
accountNum: {
minlength: 14,
maxlength: 14,
required: true
},
certify: {
required: true
},
fileOne: {
accept: "image/jpeg, image/jpg, image/png, application/pdf",
filesize: 3145728,
require_from_group: [1, '.fileGroup']
},
fileTwo: {
accept: "image/jpeg, image/jpg, image/png, application/pdf",
filesize: 3145728,
require_from_group: [1, '.fileGroup']
},
fileThree: {
accept: "image/jpeg, image/jpg, image/png, application/pdf",
filesize: 3145728,
require_from_group: [1, '.fileGroup']
},
fileFour: {
accept: "image/jpeg, image/jpg, image/png, application/pdf",
filesize: 3145728,
require_from_group: [1, '.fileGroup']
}
},
messages: {
fullName: {
required: jQuery.validator.format("- Please input your Full name as per Passport"),
maxlength: jQuery.validator.format("- Please input your Full name as per Passport")
},
emailAdd: {
required: jQuery.validator.format("- Please input your Email address"),
email: jQuery.validator.format("- Your Email address is not in the correct format")
},
accountNum: {
required: jQuery.validator.format("- Your Account number is not valid"),
minlength: jQuery.validator.format("- Your Account number is not valid"),
maxlength: jQuery.validator.format("- Your Account number is not valid")
},
certify: {
required: jQuery.validator.format("- Please acknowledge that the data you have provided is accurate")
},
fileOne: {
require_from_group: jQuery.validator.format("- Please upload a supporting document"),
accept: jQuery.validator.format("- Please upload one of the valid document types"),
filesize: jQuery.validator.format("- Please upload a file smaller than 3MB")
},
fileTwo: {
require_from_group: jQuery.validator.format("- Please upload a supporting document"),
accept: jQuery.validator.format("- Please upload one of the valid document types"),
filesize: jQuery.validator.format("- Please upload a file smaller than 3MB")
},
fileThree: {
require_from_group: jQuery.validator.format("- Please upload a supporting document"),
accept: jQuery.validator.format("- Please upload one of the valid document types"),
filesize: jQuery.validator.format("- Please upload a file smaller than 3MB")
},
fileFour: {
require_from_group: jQuery.validator.format("- Please upload a supporting document"),
accept: jQuery.validator.format("- Please upload one of the valid document types"),
filesize: jQuery.validator.format("- Please upload a file smaller than 3MB")
}
},
submitHandler: function (form) {
formData = new FormData(),
params = $(form).serializeArray(),
fileOne = $(form).find('[name = "fileOne"]')[0].files,
fileTwo = $(form).find('[name = "fileTwo"]')[0].files,
fileThree = $(form).find('[name = "fileThree"]')[0].files,
fileFour = $(form).find('[name = "fileFour"]')[0].files;
if (fileOne.length != 0) {
$.each(fileOne, function (i, file) {
formData.append('fileOne-' + i, file);
});
}
if (fileTwo.length != 0) {
$.each(fileTwo, function (i, file) {
formData.append('fileTwo-' + i, file);
});
}
if (fileThree.length != 0) {
$.each(fileThree, function (i, file) {
formData.append('fileThree-' + i, file);
});
}
if (fileFour.length != 0) {
$.each(fileFour, function (i, file) {
formData.append('fileFour-' + i, file);
});
}
$.each(params, function (i, val) {
formData.append(val.name, val.value);
});
$.ajax({
type: "POST",
url: "php/process.php",
data: formData,
dataType: "json",
mimeType: "multipart/form-data",
contentType: false,
processData: false
}).done(function (response) {
if (response == 'success') {
// window.location.replace('success.html');
} else {
console.info(response);
// window.location.replace('failure.html');
}
}).fail(function (jqXHR, textStatus, error) {
// window.location.replace('failure.html');
console.info(error);
console.info(jqXHR);
console.info(jqXHR.responseText);
console.info(textStatus);
});
return false;
},
invalidHandler: function (form, validator) {
if (!validator.numberOfInvalids())
return;
$('html, body').animate({
scrollTop: $("body").offset().top - 100
}, 2000, function () {
if ($("#fileOne").hasClass("error")) {
$("#fileOneContainer").addClass("error");
} else {
$("#fileOneContainer").removeClass("error");
}
if ($("#fileTwo").hasClass("error")) {
$("#fileTwoContainer").addClass("error");
} else {
$("#fileTwoContainer").removeClass("error");
}
if ($("#fileThree").hasClass("error")) {
$("#fileThreeContainer").addClass("error");
} else {
$("#fileThreeContainer").removeClass("error");
}
if ($("#fileFour").hasClass("error")) {
$("#fileFourContainer").addClass("error");
} else {
$("#fileFourContainer").removeClass("error");
}
});
}
});
Некоторые очевидные вещи, которые я сделаю, - это добавить некоторую проверку в JS, чтобы убедиться, что размер файла превышает 0 байт, и обновлю jQuery и jQuery до последних версий.
Кто-нибудь раньше сталкивался с подобной проблемой?
Спасибо, Рори, в этом есть смысл - честно говоря, я унаследовал этот проект от другого разработчика, а не написал его полностью сам, отсюда и все это возня.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Почему бы просто не использовать
formData = new FormData(form)и не забыть о том, что вы делаете с ручным вызовомappend()в FormData? Единственное изменение заключается в том, что вам нужно будет иметь дело с массивом файлов на сервере, но вы все равно должны это делать.