Giới hạn kích thước của tệp tải lên (phần tử đầu vào html)


80

Tôi chỉ muốn giới hạn kích thước tệp mà người dùng có thể tải lên.

Tôi đã nghĩ maxlength = 20000 = 20k nhưng điều đó dường như không hiệu quả chút nào.

Tôi đang chạy trên Rails, không phải PHP, nhưng tôi nghĩ sẽ đơn giản hơn nhiều nếu thực hiện nó ở phía máy khách trong HTML / CSS hoặc phương án cuối cùng là sử dụng jQuery. Điều này rất cơ bản mặc dù phải có một số thẻ HTML mà tôi đang thiếu hoặc không biết.

Đang tìm cách hỗ trợ IE7 +, Chrome, FF3.6 +. Tôi cho rằng tôi có thể thoát khỏi chỉ cần hỗ trợ IE8 + nếu cần.

Cảm ơn.


1
Điều đó là có thể. Hãy tham khảo câu hỏi này .
sandSK

Câu trả lời:


101

Điều này hoàn toàn có thể làm được. Sử dụng Javascript.

Tôi sử dụng jQuery để chọn phần tử đầu vào. Tôi đã thiết lập nó với một sự kiện thay đổi.

$("#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);

});

Đoạn mã trên lưu tất cả các tên tệp mà tôi cho là xứng đáng để lưu vào trang gửi trước khi quá trình gửi thực sự diễn ra. Tôi thêm các tệp "được chấp thuận" vào val của phần tử đầu vào bằng cách sử dụng jQuery để gửi biểu mẫu sẽ gửi tên của các tệp tôi muốn lưu. Tất cả các tệp sẽ được gửi, tuy nhiên, bây giờ ở phía máy chủ, chúng tôi phải lọc chúng ra. Tôi chưa viết bất kỳ mã nào cho điều đó, nhưng hãy sử dụng trí tưởng tượng của bạn. Tôi giả sử người ta có thể thực hiện điều này bằng vòng lặp for và khớp các tên được gửi từ trường nhập liệu và khớp chúng với biến $ _FILES (PHP Superglobal, xin lỗi tôi không biết biến tệp ruby).

Quan điểm của tôi là bạn có thể kiểm tra các tệp trước khi gửi. Tôi làm điều này và sau đó xuất nó cho người dùng trước khi họ gửi biểu mẫu, để cho họ biết những gì họ đang tải lên trang web của tôi. Bất kỳ thứ gì không đáp ứng tiêu chí sẽ không được hiển thị lại cho người dùng và do đó họ nên biết rằng các tệp quá lớn sẽ không được lưu. Điều này sẽ hoạt động trên tất cả các trình duyệt vì tôi không sử dụng đối tượng FormData.


25
Bạn không thể làm điều đó ở phía khách hàng và mong đợi nó luôn hoạt động. Nếu điều quan trọng là kiểm tra phía máy chủ, những người khác sẽ sử dụng các bản sao đã sửa đổi của biểu mẫu (hoặc các phương tiện phía máy khách khác) để tải lên các tệp quá khổ. Kiểm tra phía máy chủ giống như một khóa, kiểm tra phía máy khách giống như một ghi chú sau khi nó nói "giữ ngoài". Trước tiên hãy khóa cửa, sau đó cắm biển "cấm cửa".
user340140

2
@ user340140 Miễn là máy khách hỗ trợ javascript là được. Nếu khách hàng không chỉ đơn giản nói rằng trang web yêu cầu javascript để được kích hoạt. Javascript có một trình đọc tệp về cơ bản không thể bị lừa, nó đọc từng chút một nên không phải lo lắng về việc nhận một tệp nhỏ bí mật có kích thước khác. Phía máy chủ là phương pháp "an toàn" được ưa thích, nhưng tôi không thấy javascript không an toàn như thế nào khi nói về kích thước tệp.
mark.inman

6
Vì như user340140 đã nói Javascript có thể dễ dàng sửa đổi bất cứ điều gì bạn làm. Bạn có thể thực hiện việc này khi kiểm tra khả năng sử dụng của phía máy chủ, nhưng bạn không thể bảo mật bằng Javascript phía máy khách.
Sinan Samet

Chỉ sử dụng mã JavaScript (phía máy khách) là không khả thi vì nó có thể dễ dàng bị bỏ qua. Cần có logic phía máy chủ.
Akshay Anurag

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

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

Ví dụ này sẽ hoạt động tốt. Tôi thiết lập nó cho khoảng 2MB, 1MB tính bằng Byte là 1,048,576 để bạn có thể nhân nó với giới hạn bạn cần.

Đây là ví dụ jsfiddle để rõ ràng hơn:
https://jsfiddle.net/7bjfr/808/


Chỉ sử dụng mã JavaScript (phía máy khách) là không khả thi vì nó có thể dễ dàng bị bỏ qua. Cần có logic phía máy chủ.
Akshay Anurag

8
@AkshayAnurag phía khách hàng xác nhận ngăn chặn lãng phí thời gian của khách hàng và băng thông của máy chủ, nó không phải là về an ninh của nó về UX
Arash Moosapour

Bảo mật không bao giờ quan trọng hơn UX. Nếu việc giới hạn kích thước tệp là quan trọng thì hãy làm điều đó ở phần back-end. Nếu bạn thực sự muốn làm điều đó trong giao diện người dùng thì có nhiều cách tốt hơn để làm điều đó.
Akshay Anurag

13
@AkshayAnurag bạn chỉ có thể kiểm tra kích thước hình ảnh trên phụ trợ sau khi toàn bộ hình ảnh được tải lên và nếu đó là một hình ảnh lớn, giả sử 16mb và ứng dụng khách có kết nối chậm hơn người dùng sẽ phải đợi toàn bộ thời gian hình ảnh được tải lên chỉ để lấy lỗi ở cuối. Để ngăn chặn điều gì đó tương tự, bạn cần một số loại xác thực trên giao diện người dùng. Xin vui lòng cho tôi biết nếu tôi sai hoặc thiếu một cái gì đó hoặc có thể bạn có một cái gì đó để ngăn chặn điều này?
Haseeb Rehman

27

Bạn không thể làm điều đó ở phía máy khách. Bạn sẽ phải làm điều đó trên máy chủ.

Chỉnh sửa: Câu trả lời này đã lỗi thời!

Tại thời điểm chỉnh sửa này, API tệp HTML hiện được hỗ trợ trên tất cả các trình duyệt chính .

Tôi muốn cung cấp một bản cập nhật với giải pháp, nhưng @ mark.inman.winning đã làm được .

Hãy nhớ rằng ngay cả khi bây giờ có thể xác thực trên máy khách, bạn vẫn nên xác thực nó trên máy chủ. Tất cả các xác thực phía máy khách có thể bị bỏ qua.


2
Vâng, điều đó là không thể ngay bây giờ. Có một số bản nháp của api tệp mới trong HTML5, nhưng không có trình duyệt nào hỗ trợ đầy đủ vào lúc này.
Ortiga

2
Hãy xem: cs.tut.fi/~jkorpela/forms/file.html , "Đặt hạn chế về kích thước tệp", để biết lý do tại sao cố gắng thực hiện việc này ở phía máy khách là vô ích.
magma

Bạn không có quyền truy cập vào hệ thống tệp cục bộ trên máy tính của khách truy cập, điều tốt nhất bạn có thể hy vọng là để apache giới hạn kích thước tệp và dừng tải lên nếu nó quá lớn.
Brent Friar

Thật ngu ngốc khi làm điều đó ở phía máy khách - trừ khi bạn chỉ muốn tạo sự thuận tiện cho người dùng. "Bạn phải xác thực phía máy chủ. Bạn có thể xác thực phía máy khách."
d -_- b

2
Thật thú vị ... điều này có vẻ hoạt động: plupload.com . Vấn đề duy nhất là IE8 không có các plugin flash, silverlight, gears, v.v. sẽ mặc định là HTML4.
delphi

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" />

Nếu bạn cần xác thực loại tệp , hãy viết bình luận bên dưới và tôi sẽ chia sẻ giải pháp của mình.

(Spoiler: acceptthuộc tính không phải là giải pháp chống đạn)


2

Ví dụ về tệp video (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
Vui lòng thử thêm một số giải thích với mã của bạn.
Partho63

Chỉ sử dụng mã JavaScript (phía máy khách) là không khả thi vì nó có thể dễ dàng bị bỏ qua. Cần có logic phía máy chủ.
Akshay Anurag
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.