Обмежте розмір завантаженого файлу (елемент введення HTML)


80

Я хотів би просто обмежити розмір файлу, який користувач може завантажити.

Я думав, що maxlength = 20000 = 20k, але, здається, це взагалі не працює.

Я працюю на Rails, а не на PHP, але думав, що було б набагато простіше зробити це на стороні клієнта в HTML / CSS або в крайньому випадку за допомогою jQuery. Це настільки базово, що, мабуть, існує якийсь тег HTML, якого я бракую або не знаю.

Хочемо підтримати IE7 +, Chrome, FF3.6 +. Думаю, я міг би піти, просто підтримавши IE8 +, якщо це необхідно.

Дякую.


1
Можливо. Будь ласка, зверніться до цього питання.
sandSK

Відповіді:


101

Це цілком можливо. Використовуйте Javascript.

Я використовую jQuery для вибору вхідного елемента. Я налаштував це на подію зміни.

$("#aFile_upload").on("change", function (e) {

    var count=1;
    var files = e.currentTarget.files; // puts all files into an array

    // call them as such; files[0].size will get you the file size of the 0th file
    for (var x in files) {

        var filesize = ((files[x].size/1024)/1024).toFixed(4); // MB

        if (files[x].name != "item" && typeof files[x].name != "undefined" && filesize <= 10) { 

            if (count > 1) {

                approvedHTML += ", "+files[x].name;
            }
            else {

                approvedHTML += files[x].name;
            }

            count++;
        }
    }
    $("#approvedFiles").val(approvedHTML);

});

Наведений вище код зберігає всі імена файлів, які, на мою думку, гідні збереження, на сторінці подання до того, як подання станеться насправді. Я додаю "затверджені" файли у val елемента введення за допомогою jQuery, щоб форма надіслала імена файлів, які я хочу зберегти. Усі файли будуть надіслані, проте зараз на стороні сервера нам доведеться їх відфільтрувати. Я ще не написав для цього жодного коду, але використовуйте свою уяву. Я припускаю, що це можна зробити за допомогою циклу for та зіставлення імен, надісланих із поля введення, і зіставити їх із змінною $ _FILES (PHP Superglobal, вибачте, я не знаю змінну файлу ruby).

Я хочу сказати, що ви можете перевірити файли перед поданням. Я роблю це, а потім виводжу користувачеві перед тим, як він / вона подає форму, щоб повідомити їх, що вони завантажують на мій сайт. Все, що не відповідає критеріям, не відображається користувачеві, і тому вони повинні знати, що занадто великі файли не будуть збережені. Це має працювати у всіх браузерах, оскільки я не використовую об’єкт FormData.


25
Ви не можете зробити це на стороні клієнта і очікувати, що це завжди спрацює. Якщо це важливо також перевірити на стороні сервера, інакше люди будуть використовувати змінені копії форми (або інші засоби на стороні клієнта) для завантаження великогабаритних файлів. Серверні перевірки схожі на замок, перевірки на стороні клієнта - як примітка після надсилання, на якій написано "триматися подалі". Спочатку зафіксуйте двері, потім поставте знак "триматися подалі".
user340140

2
@ user340140 Поки клієнт підтримує javascript, ви можете. Якщо клієнт не просто заявляє, що на сайті потрібно активувати javascript. У Javascript є програма для зчитування файлів, яку, по суті, неможливо обдурити, вона читається поступово, тому не потрібно турбуватися про отримання невеликого файлу, який є таємно іншого розміру. Серверна сторона є кращим "безпечним" методом, але я не бачу, як javascript не такий безпечний, коли йдеться про розмір файлу.
mark.inman

6
Тому що, як і user340140, зазначений Javascript можна легко змінити, що б ви не робили. Ви можете зробити це поверх серверної перевірки на зручність використання, але ви не можете захистити його за допомогою клієнтського Javascript.
Сінан Самет

Використання лише коду JavaScript (на стороні клієнта) неможливо, оскільки його можна легко обійти. Потрібна логіка на стороні сервера.
Akshay Anurag

83
var uploadField = document.getElementById("file");

uploadField.onchange = function() {
    if(this.files[0].size > 2097152){
       alert("File is too big!");
       this.value = "";
    };
};

Цей приклад повинен працювати нормально. Я встановив його приблизно на 2 МБ, 1 МБ в байтах - 1048 576, тому ви можете помножити його на потрібний ліміт.

Ось приклад jsfiddle для більшої чіткості:
https://jsfiddle.net/7bjfr/808/


Використання лише коду JavaScript (на стороні клієнта) неможливо, оскільки його можна легко обійти. Потрібна логіка на стороні сервера.
Акшай Анураг,

9
@AkshayAnurag перевірка на стороні клієнта запобігає втраті часу клієнта та пропускної здатності сервера, а не про безпеку, а про UX
Arash Moosapour

Безпека ніколи не важливіша за UX. Якщо обмеження розміру файлу важливо, зробіть це у фоновому режимі. Якщо ви дійсно хочете зробити це в інтерфейсі, то є кращі способи зробити це.
Акшай Анураг

14
@AkshayAnurag ви можете перевірити розмір зображення у сервісній системі лише після того, як завантажено ціле зображення, і якщо це величезне зображення, скажімо, 16 Мб і клієнт мають повільне з'єднання, ніж користувачеві доведеться чекати весь час завантаження зображення, лише помилка в кінці. Щоб запобігти щось подібне, вам потрібна якась перевірка на інтерфейсі. Будь ласка, дайте мені знати, якщо я помиляюсь або щось пропускаю, чи, можливо, у вас є що запобігти цьому?
Хасіб Рехман,

27

Ви не можете зробити це на стороні клієнта. Вам доведеться це робити на сервері.

Редагувати: Ця відповідь застаріла!

На час редагування API файлів HTML тепер підтримується у всіх основних браузерах .

Я б запропонував оновлення з рішенням, але @ mark.inman.winning це вже зробив .

Майте на увазі, що навіть якщо зараз можливо перевірити на клієнті, ви все одно повинні перевірити це на сервері. Усі перевірки на стороні клієнта можна обійти.


2
Так, зараз це неможливо. У HTML5 є кілька чернеток нового файлу api, але на даний момент жоден браузер не підтримує його повністю.
Ортіга,

2
Дивіться: cs.tut.fi/~jkorpela/forms/file.html , "Встановлення обмежень на розмір файлу", про те, чому спроби робити це на стороні клієнта безглуздо.
магма

У вас немає доступу до локальної файлової системи на комп’ютері відвідувачів, найкраще, на що ви можете сподіватися, - це встановити Apache обмеження розміру файлу та зупинити завантаження, якщо він занадто великий.
Брент Фріар,

Дурно робити це на стороні клієнта - якщо ви просто не хочете зробити це зручним для користувача. "Ви повинні перевірити сторону сервера. Ви можете перевірити сторону клієнта."
d -_- b

2
Цікаво ... це, здається, працює: plupload.com . Єдина проблема полягає в тому, що IE8 без плагінів flash, silverlight, gears і т.п. за замовчуванням буде HTML4, здається.
дельфі

7

const input = document.getElementById('input')

input.addEventListener('change', (event) => {
  const target = event.target
  	if (target.files && target.files[0]) {

      /*Maximum allowed size in bytes
        5MB Example
        Change first operand(multiplier) for your needs*/
      const maxAllowedSize = 5 * 1024 * 1024;
      if (target.files[0].size > maxAllowedSize) {
      	// Here you can ask your users to load correct file
       	target.value = ''
      }
  }
})
<input type="file" id="input" />

Якщо вам потрібно перевірити тип файлу , напишіть у коментарях нижче, і я поділюсь своїм рішенням.

(Спойлер: acceptатрибут не є куленепробивним рішенням)


2

Приклад відеофайлу (HTML + Javascript):

function upload_check()
{
    var upl = document.getElementById("file_id");
    var max = document.getElementById("max_id").value;

    if(upl.files[0].size > max)
    {
       alert("File too big!");
       upl.value = "";
    }
};
<form action="some_script" method="post" enctype="multipart/form-data">
    <input id="max_id" type="hidden" name="MAX_FILE_SIZE" value="250000000" />
    <input onchange="upload_check()" id="file_id" type="file" name="file_name" accept="video/*" />
    <input type="submit" value="Upload"/>
</form>


1

const input = document.getElementById('input')

input.addEventListener('change', (event) => {
  const target = event.target
  	if (target.files && target.files[0]) {

      /*Maximum allowed size in bytes
        5MB Example
        Change first operand(multiplier) for your needs*/
      const maxAllowedSize = 5 * 1024 * 1024;
      if (target.files[0].size > maxAllowedSize) {
      	// Here you can ask your users to load correct file
       	target.value = ''
      }
  }
})
<input type="file" id="input" />


-1
<script type="text/javascript">
    $(document).ready(function () {

        var uploadField = document.getElementById("file");

        uploadField.onchange = function () {
            if (this.files[0].size > 300000) {
                this.value = "";
                swal({
                    title: 'File is larger than 300 KB !!',
                    text: 'Please Select a file smaller than 300 KB',
                    type: 'error',
                    timer: 4000,
                    onOpen: () => {
                        swal.showLoading()
                        timerInterval = setInterval(() => {
                            swal.getContent().querySelector('strong')
                                .textContent = swal.getTimerLeft()
                        }, 100)
                    },
                    onClose: () => {
                        clearInterval(timerInterval)

                    }
                }).then((result) => {
                    if (
                        // Read more about handling dismissals
                        result.dismiss === swal.DismissReason.timer


                    ) {

                        console.log('I was closed by the timer')
                    }
                });

            };
        };



    });
</script>

1
Будь ласка, спробуйте додати до свого коду кілька пояснень.
Partho63

Використання лише коду JavaScript (на стороні клієнта) неможливо, оскільки його можна легко обійти. Потрібна логіка на стороні сервера.
Akshay Anurag
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.