Bỏ qua để đến nội dung chính

Xác thực tệp

Dropup cung cấp xác thực tệp toàn diện để đảm bảo chỉ các tệp hợp lệ được chấp nhận.

Tùy chọn xác thực

Accept (Loại tệp)

Chỉ định loại tệp được chấp nhận:

// Chỉ chấp nhận hình ảnh
useDropup({ accept: 'image/*' });

// Chấp nhận các loại cụ thể
useDropup({ accept: 'image/png, image/jpeg' });

// Chấp nhận theo phần mở rộng
useDropup({ accept: '.pdf, .doc, .docx' });

// Nhiều danh mục
useDropup({ accept: ['image/*', 'application/pdf', '.txt'] });

Các mẫu Accept phổ biến

MẫuMô tả
image/*Tất cả hình ảnh
image/png, image/jpegChỉ PNG và JPEG
video/*Tất cả video
audio/*Tất cả tệp âm thanh
application/pdfChỉ tệp PDF
.doc, .docxTài liệu Word
*/*Tất cả tệp (mặc định)

Giới hạn kích thước tệp

useDropup({
maxSize: 10 * 1024 * 1024, // Tối đa 10MB
minSize: 1024, // Tối thiểu 1KB
});

Giới hạn số lượng tệp

useDropup({
maxFiles: 5, // Tối đa 5 tệp
});

Giới hạn kích thước hình ảnh

useDropup({
accept: 'image/*',
maxWidth: 4096, // Chiều rộng tối đa tính bằng pixel
maxHeight: 4096, // Chiều cao tối đa tính bằng pixel
minWidth: 100, // Chiều rộng tối thiểu tính bằng pixel
minHeight: 100, // Chiều cao tối thiểu tính bằng pixel
});

Quy tắc xác thực tùy chỉnh

Tạo logic xác thực tùy chỉnh:

useDropup({
customRules: [
// Quy tắc 1: Kiểm tra độ dài tên tệp
(file) => {
if (file.name.length > 100) {
return 'Tên tệp phải ít hơn 100 ký tự';
}
return true;
},

// Quy tắc 2: Kiểm tra nội dung cụ thể
(file) => {
if (file.name.includes('draft')) {
return 'Không cho phép tệp nháp';
}
return true;
},

// Quy tắc 3: Xác thực bất đồng bộ
async (file) => {
const hash = await calculateHash(file);
const exists = await checkDuplicate(hash);
if (exists) {
return 'Tệp này đã được tải lên';
}
return true;
},
],
});

Giá trị trả về của quy tắc

Giá trị trả vềÝ nghĩa
trueXác thực thành công
falseXác thực thất bại (lỗi chung)
stringXác thực thất bại với thông báo tùy chỉnh

Xử lý lỗi xác thực

Sử dụng callback onValidationError:

useDropup({
accept: 'image/*',
maxSize: 5 * 1024 * 1024,
onValidationError: (errors) => {
errors.forEach(({ file, errors: fileErrors }) => {
console.log(`${file.name} xác thực thất bại:`);
fileErrors.forEach(error => console.log(` - ${error}`));
});

// Hiển thị thông báo thân thiện với người dùng
toast.error(`${errors.length} tệp xác thực thất bại`);
},
});

Cấu trúc lỗi xác thực

interface ValidationError {
file: File; // Tệp thất bại
errors: string[]; // Mảng thông báo lỗi
}

Quy tắc xác thực có sẵn

Dropup bao gồm các quy tắc xác thực phổ biến:

import { commonRules } from '@samithahansaka/dropup';

useDropup({
customRules: [
commonRules.noExecutables, // Chặn .exe, .bat, v.v.
commonRules.noHiddenFiles, // Chặn tệp bắt đầu bằng .
commonRules.maxFilenameLength(50),
commonRules.allowedExtensions(['.jpg', '.png', '.pdf']),
],
});

Phản hồi xác thực khi kéo

Cung cấp phản hồi trực quan khi kéo:

function DropZone() {
const { getDropProps, state } = useDropup({
accept: 'image/*',
});

// state.isDragAccept - tệp khớp với tiêu chí accept
// state.isDragReject - tệp không khớp

return (
<div
{...getDropProps()}
style={{
borderColor: state.isDragAccept
? 'green'
: state.isDragReject
? 'red'
: 'gray',
}}
>
{state.isDragReject && <p>Loại tệp không được chấp nhận!</p>}
</div>
);
}

Ví dụ xác thực hoàn chỉnh

import { useDropup, commonRules } from '@samithahansaka/dropup';

function SecureUploader() {
const { files, state, getDropProps, getInputProps } = useDropup({
// Loại tệp
accept: ['image/jpeg', 'image/png', 'application/pdf'],

// Giới hạn kích thước
maxSize: 10 * 1024 * 1024, // 10MB
minSize: 100, // 100 bytes (ngăn tệp rỗng)

// Giới hạn số lượng
maxFiles: 10,

// Kích thước hình ảnh (chỉ cho hình ảnh)
maxWidth: 8000,
maxHeight: 8000,

// Quy tắc tùy chỉnh
customRules: [
commonRules.noExecutables,
commonRules.maxFilenameLength(100),

// Tùy chỉnh: không có tệp có khoảng trắng
(file) => {
if (file.name.includes(' ')) {
return 'Tên tệp không được chứa khoảng trắng';
}
return true;
},
],

// Xử lý lỗi
onValidationError: (errors) => {
errors.forEach(({ file, errors }) => {
alert(`${file.name}: ${errors.join(', ')}`);
});
},
});

return (
<div
{...getDropProps()}
className={`dropzone ${
state.isDragReject ? 'reject' : state.isDragAccept ? 'accept' : ''
}`}
>
<input {...getInputProps()} />
{state.isDragReject ? (
<p>Một số tệp sẽ bị từ chối</p>
) : (
<p>Thả tệp vào đây (chỉ JPEG, PNG, PDF, tối đa 10MB)</p>
)}
</div>
);
}