$ _FILE передает файл из JS в скрипт PHP с 0 байтами (с использованием jQuery validate v1.14.0 и jQuery v3.2.1)

У меня есть веб-форма, которая позволяет пользователю выбрать до 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 до последних версий.

Кто-нибудь раньше сталкивался с подобной проблемой?

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

Rory McCrossan 14.08.2018 10:33

Спасибо, Рори, в этом есть смысл - честно говоря, я унаследовал этот проект от другого разработчика, а не написал его полностью сам, отсюда и все это возня.

John O'Sullivan 14.08.2018 12:58
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
31
0

Другие вопросы по теме