Resource
https://joji.me/en-us/blog/processing-huge-files-using-filereader-readasarraybuffer-in-web-browser/
https://api.video/blog/tutorials/uploading-large-files-with-javascript
https://aspdotnet.tistory.com/1970
https://riptutorial.com/javascript/example/16626/slice-a-file
https://not-to-be-reset.tistory.com/102
https://www.positronx.io/understand-html5-filereader-api-to-upload-image-and-text-files/
웹에서 가장 일반적으로 사용되는 기능 중 하나로, 사용자는 자신의 로컬 장치에서 파일을 선택하고 상호 작용할 수 있습니다. 이를 통해 사용자는 파일을 선택하여 서버에 업로드할 수 있습니다(예: 사진 업로드 또는 세금 문서 제출 등). 그러나 사이트에서 네트워크를 통해 데이터를 전송할 필요 없이 파일을 읽고 조작할 수도 있습니다.
최신 파일 시스템 액세스 API #
파일 시스템 액세스 API는 사용자의 로컬 시스템에 있는 파일과 디렉토리를 읽고 쓸 수 있는 간편한 방법을 제공합니다. 이는 현재 Chrome 또는 Edge와 같은 대부분의 Chromium 파생 브라우저에서 사용할 수 있습니다. 자세한 내용은 파일 시스템 액세스 API 문서를 참조하세요.
파일 시스템 액세스 API는 아직 모든 브라우저와 호환되지 않기 때문에 새로운 API를 사용할 수 있는 곳이라면 어디에서나 사용하지만 그렇지 않은 경우에는 레거시 접근 방식으로 대체하는 도우미 라이브러리인 browser-fs-access를 확인해 보세요.
파일 작업, 고전적인 방식 #
이 가이드에서는 다음을 수행하는 방법을 보여줍니다.
파일 선택 #
HTML 입력 요소 #
사용자가 파일을 선택할 수 있도록 하는 가장 쉬운 방법은 모든 주요 브라우저에서 지원되는 <input type="file"> 요소를 사용하는 것입니다. 이를 클릭하면 사용자가 운영 체제의 내장 파일 선택 UI를 사용하여 하나의 파일, 또는 multiple 속성이 포함된 경우 여러 파일을 선택할 수 있습니다. 사용자가 하나 또는 여러 파일의 선택을 마치면 이 요소의 change 이벤트가 시작됩니다. FileList 객체인 event.target.files에서 파일 목록에 액세스할 수 있습니다. FileList의 각 항목은 File 객체입니다.
<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
window.showOpenFilePicker() 메서드가 해당 사용 사례에 효과적인 대안인지 확인하세요. 읽기와 별도로 파일에 다시 쓸 수 있도록 파일 핸들도 제공하기 때문입니다. 이 메서드는 폴리필할 수 있습니다.
이 예에서는 사용자가 운영 체제의 내장 파일 선택 UI를 사용하여 여러 파일을 선택한 다음 선택한 각 파일을 콘솔에 기록할 수 있습니다.
사용자가 선택할 수 있는 파일 유형 제한 #
경우에 따라 사용자가 선택할 수 있는 파일 유형을 제한해야 할 수 있습니다. 예를 들어 이미지 편집 앱은 텍스트 파일이 아닌 이미지만 허용해야 합니다. 이를 위해 입력 요소에 accept 속성을 추가하여 어떤 파일이 허용되는지 지정할 수 있습니다.
<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">
사용자 지정 드래그 앤 드롭 #
일부 브라우저에서 <input type="file"> 요소는 사용자가 파일을 앱으로 끌어다 놓을 수 있도록 하는 드롭 대상이기도 합니다. 그러나 드롭 대상이 작아 사용하기 어려울 수 있습니다. 그래서, <input type="file"> 요소를 사용하여 핵심 기능을 제공한 후에는 큰 사용자 지정 끌어서 놓기 표면을 제공할 수 있습니다.
DataTransferItem.getAsFileSystemHandle()메서드가 해당 사용 사례에 효과적인 대안인지 확인하세요. 읽기와 별도로 파일에 다시 쓸 수 있도록 파일 핸들도 제공하기 때문입니다.
드롭 영역 선택 #
드롭 표면은 애플리케이션의 디자인에 따라 다릅니다. 창의 일부만 드롭 표면이 되도록 하거나 잠재적으로 전체 창을 드롭 표면으로 원할 수 있습니다.
Squoosh는 전체 창을 드롭 영역으로 만듭니다.
Squoosh를 사용하면 사용자가 창의 아무 곳이나 이미지를 끌어다 놓을 수 있으며 이미지 선택을 클릭하면 <input type="file"> 요소가 호출됩니다. 드롭 영역으로 무엇을 선택하든 사용자가 파일을 해당 표면으로 끌어다 놓을 수 있다는 점을 분명히 알도록 해야 합니다.
드롭 영역 정의 #
요소를 드래그 앤 드롭 영역으로 설정하려면 dragover 및 drop이라는 두 가지 이벤트에 수신 대기해야 합니다. dragover 이벤트는 드래그 앤 드롭 작업으로 파일 복사본이 만들어진다는 것을 시각적으로 나타내도록 브라우저 UI를 업데이트합니다. drop 이벤트는 사용자가 파일을 표면에 놓은 후에 시작됩니다. 입력 요소와 유사하게 FileList 객체인 event.dataTransfer.files에서 파일 목록에 액세스할 수 있습니다. FileList의 각 항목은 File 객체입니다.
const dropArea = document.getElementById('drop-area');
dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});
dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});
event.stopPropagation() 및 event.preventDefault()는 브라우저의 기본 동작이 발생하지 않도록 하고 대신 코드가 실행되도록 합니다. 그렇지 않으면 브라우저가 페이지에서 벗어나 사용자가 브라우저 창에 놓은 파일을 열게 됩니다.
라이브 데모를 보려면 사용자 지정 드래그 앤 드롭을 확인하세요.
디렉토리는 어떻습니까? #
불행히도 현재 디렉토리에 액세스할 수 있는 좋은 방법은 없습니다.
<input type="file"> 요소의 webkitdirectory 속성을 사용하면 사용자가 디렉토리를 선택할 수 있습니다. 일부 Chromium 기반 브라우저 및 데스크톱 Safari에서는 지원되지만 브라우저 호환성에 대한 상충되는 보고가 있습니다.
window.showDirectoryPicker() 메서드가 해당 사용 사례에 효과적인 대안인지 확인하세요. 읽기와 별도로 디렉토리에 다시 쓸 수 있도록 디렉토리 핸들도 제공하기 때문입니다. 이 메서드는 폴리필할 수 있습니다.
드래그 앤 드롭이 활성화된 경우 사용자는 드롭 영역에 디렉토리를 끌어가려고 할 수 있습니다. 드롭 이벤트가 발생하면 여기에 디렉토리에 대한 File 객체가 포함되지만 디렉토리 내의 어떤 파일에도 액세스할 수 없습니다.
파일 메타데이터 읽기 #
File객체에는 파일에 관한 여러 메타데이터 속성이 포함되어 있습니다. 대부분의 브라우저는 파일 이름, 파일 크기 및 MIME 유형을 제공하지만 플랫폼에 따라 브라우저마다 다르거나 추가적인 정보를 제공할 수 있습니다.
function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}
input-type-fileGlitch 데모에서 실제 작동하는 모습을 볼 수 있습니다.
파일 내용 읽기 #
파일을 읽으려면 FileReader를 사용하세요. 그러면 File 객체의 콘텐츠를 메모리로 읽을 수 있습니다. 파일을 배열 버퍼, 데이터 URL 또는 텍스트로 읽도록 FileReader에 지시할 수 있습니다.
function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}
위의 예는 사용자가 제공한 File을 읽어 데이터 URL로 변환하고 해당 데이터 URL을 사용하여 img 요소에 이미지를 표시합니다. 사용자가 이미지 파일을 선택했는지 확인하는 방법을 보려면 read-image-file Glitch를 살펴보세요.
파일 읽기 진행률 모니터링 #
대용량 파일을 읽을 때 읽기 진행 정도를 나타내는 UX를 제공하면 도움이 될 수 있습니다. 이를 위해 FileReader에서 제공하는 progress 이벤트를 사용합니다. progress 이벤트는 두 가지 속성, 즉 읽은 양인 loaded와 읽어야 할 총량인 total을 제공합니다.
function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}
'Study > JavaScript' 카테고리의 다른 글
Javascript Coding Convention (0) | 2022.02.25 |
---|---|
Javascript 20가지 팁 || 개발시간을 줄이자 (0) | 2022.02.25 |
Javascript 보석 같은 한 줄짜리 코드 (0) | 2022.02.16 |
일상적인 문제에 유용한 12가지 자바스크립트 스니펫 (0) | 2021.12.31 |
자주 쓰이는 자바스크립트 15가지 (0) | 2021.12.27 |