// 파일 드래그& 드롭 이벤트
// 드래그 영역에 진입했을 때
$uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
$uploadArea.classList.add('dragover');
});
// 드래그 영역에서 나갔을 때
$uploadArea.addEventListener('dragleave', (e) => {
e.preventDefault();
$uploadArea.classList.remove('dragover');
});
// 드래그 영역에 드롭했을 때
$uploadArea.addEventListener('drop', (e) => {
e.preventDefault(); // 드롭했을 때 이미지 새탭이 열리거나 파일이 다운로드되는 것을 방지
// 파일 정보 얻어오기 : event 객체의 dataTransfer.files()
const files = [...e.dataTransfer.files];
// 파일 검증
if (files.length > 0) handleFiles(files);
});
input[type="file"]로 받은 파일을 검증하는 방법
<!-- 파일 입력 요소 -->
<input type="file" id="fileInput" multiple />
<!-- 이미지 미리보기용 요소 -->
<img id="preview" alt="Image Preview" style="max-width: 200px; display: none;" />
// 허용되는 MIME 타입
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
// 허용되는 파일 확장자
const allowedExtensions = ['jpg', 'png', 'pdf'];
// 허용되는 최대 파일 크기 (5MB)
const maxSize = 5 * 1024 * 1024;
// 허용되는 최대 파일 개수
const maxFiles = 5;
// 파일 입력 요소 및 미리보기 이미지 요소
const fileInput = document.querySelector('#fileInput');
const preview = document.querySelector('#preview');
// 파일 입력 이벤트 리스너 추가 :
// : input[type=file]의 change 이벤트가 발생하면
// e.target.files 객체와 관련 정보 전달됨
fileInput.addEventListener('change', (event) => {
const files = event.target.files; // 선택된 파일 리스트
// (1) 파일 개수 검증
if (files.length > maxFiles) {
console.error('Too many files selected'); // 오류 메시지 출력
return; // 검증 실패 시 종료
}
// (2) 선택된 파일들 반복 검증
Array.from(files).forEach((file) => {
// (2-1) 파일 유형 검증
if (!allowedTypes.includes(file.type)) {
console.error(`${file.name} has an invalid type`); // 잘못된 파일 유형 경고
return; // 검증 실패 시 종료
}
// (2-2) 파일 크기 검증
if (file.size > maxSize) {
console.error(`${file.name} is too large`); // 파일 크기 초과 경고
return; // 검증 실패 시 종료
}
// (2-3) 파일 확장자 검증
const fileExtension = file.name.split('.').pop().toLowerCase(); // 파일 확장자 추출
if (!allowedExtensions.includes(fileExtension)) {
console.error(`${file.name} has an invalid extension`); // 잘못된 확장자 경고
return; // 검증 실패 시 종료
}
// 검증 통과 메시지
console.log(`${file.name} is valid`);
// (3) 이미지 미리보기
if (file.type.startsWith('image/')) { // startswith로 파일이 이미지인지 확인
const reader = new FileReader(); // FileReader 객체 생성
reader.onload = (e) => {
preview.src = e.target.result; // 이미지 URL 설정
preview.style.display = 'block'; // 이미지 요소 표시
};
reader.readAsDataURL(file); // 이미지 파일을 읽어 데이터 URL로 변환
}
});
});
파일을 fetch 할 때는,
1) 파일(파일+json을 보낼 경우는 json도)을 FormData로 만들어 준 후,
2) fetch의 body를 FormData로 설정해준다.fetch의 body에 FormData를 보내준다.
검색용 : formData, append, blob
// 1. formdata를 생성하여
const formData = new Formadata();
//2. formdata 안에 보내려는 데이터를 apped 해준다
// - json 객체라면 아래 형식으로 append
// : formData.append(key, key value, {data type})
// : 이 때, key value는 1) json으로 만들어 준 후 2) 대용량이므로 Blob 객체로 변환해줌
formData.append(key name, new Blob([JSON.stringify(feedData)], {
type: 'application/json'
}));
// - 파일이라면 아래 형식으로 append
// : formData.append(key, key value)
// : 이 때, 파일을 한 번에 여러 파일 못 보내므로 반복문으로 돌려준다.
imageFiles.forEach(file => {
formData.append('images', file);
});
// 3. 서버에 전송 요청
// - 보통 Post FETCH 할 때 fetch(url, {method:, headers: {'content-type': $$$$}, body: }
// 이런 식으로 headers에 content-type을 넣어서 보내지만,
// 이 경우에는 위에 2번에서 content-type 정의했으므로 fetch 할 때는 생략함
fetch(url, {
method: 'POST',
body: formData
});