<input type="file">
===================

**`file`** 유형의 `<input>` (en-US) 요소에는 저장 장치의 파일을 하나 혹은 여러 개 선택할 수 있습니다. 그 후, 양식을 제출해 서버로 전송하거나, File API를 사용한 JavaScript 코드로 조작할 수 있습니다.

시도해보기
-----

|  |  |
| --- | --- |
| **값** | 선택한 파일의 경로를 나타내는 `DOMString`. |
| **이벤트** | `change`,
 `input` |
| **지원하는 공통 특성** | `required` (en-US) |
| **추가 특성** | `accept`,
 `capture`,
 `files`,
 `multiple` |
| **IDL 특성** | `files`, `value` |
| **DOM 인터페이스** | `HTMLInputElement` (en-US) |
| **메서드** | `select()` (en-US) |

값
-

파일 입력 칸의 `value` (en-US) 특성은 선택한 파일의 경로를 나타내는 `DOMString`을 담습니다. 사용자가 여러 개의 파일을 선택한 경우 `value`는 파일 목록의 첫 번째 파일을 가리키며, 나머지 파일은 요소의 `HTMLInputElement.files` (en-US) 속성으로 가져올 수 있습니다.

> 
> \*\*참고:\*\*1. 아직 아무런 파일도 선택하지 않은 경우 빈 문자열(`""`)을 사용합니다. 2. 악의적인 소프트웨어가 사용자의 파일 구조를 알아내는 것을 방지하기 위해, 값 문자열은 항상 C:\fakepath\를 앞에 포함합니다.
> 
> 
> 

추가 특성
-----

모든 `<input>` (en-US) 요소의 공용 특성 외에도, `file` 유형은 아래의 특성도 지원합니다.

| 특성 | 설명 |
| --- | --- |
| `accept` | 허용하는 파일 유형을 나타내는 하나 이상의 고유 파일 유형 지정자 |
| `capture` | 이미지 또는 비디오 데이터를 캡처할 때 사용할 방법 |
| `files` | 선택한 파일을 나열하는 `FileList` |
| `multiple` | 지정할 경우 사용자가 여러 개의 파일을 선택할 수 있음 |

### `accept`

`accept` (en-US) 특성은 파일 입력 칸이 허용할 파일 유형을 나타내는 문자열로, 쉼표로 구분한 **고유 파일 유형 지정자**의 목록입니다. 주어진 파일 유형의 식별 방법이 여러 가지일 수도 있으므로, 특정 파일 형식이 필요할 땐 유형의 집합을 제공하는 것이 좋습니다.

예를 들어, Microsoft Word 파일을 식별하는 방법은 여러가지이므로, Word 파일을 허용하는 `<input>`은 다음과 같은 형태를 갖게 됩니다.


```html
<input
 type="file"
 id="docpicker"
 accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
```

### `capture`

`accept` (en-US) 특성이 이미지나 비디오 캡처 데이터를 요구할 경우, `capture` (en-US) 특성으로는 어떤 카메라를 사용할지 지정할 수 있습니다. `user` 값은 전면 카메라(사용자를 향한 카메라)와 마이크를, `environment` 값은 후면 카메라와 마이크를 사용해야 함을 나타냅니다. `capture` 특성을 누락한 경우 사용자 에이전트가 어떤 쪽을 선택할지 스스로 결정합니다. 요청한 방향의 카메라를 사용할 수 없는 경우 사용자 에이전트는 자신이 선호하는 기본 모드로 대체할 수 있습니다.

**참고:** `capture`는 과거 불리언 특성이었으며, 존재할 경우 파일 선택 창을 요청하는 대신 장치의 카메라나 마이크 등 미디어 캡처 장치를 요청했었습니다.

### `files`

선택한 모든 파일을 나열하는 `FileList` 객체입니다. `multiple` 특성을 지정하지 않았다면 두 개 이상의 파일을 포함하지 않습니다.

### `multiple`

`multiple` (en-US) 불리언 특성을 지정한 경우 사용자가 파일 선택 창에서 복수의 파일을 선택할 수 있습니다.

비표준 특성
------

위의 표준 특성 외에도, 다음과 같이 일부 브라우저에서만 사용할 수 있는 비표준 특성도 존재합니다. 지원하지 않는 브라우저에서의 코드 동작에 제약이 생길 수 있으므로, 가능하면 사용을 피해야 합니다.

| 특성 | 설명 |
| --- | --- |
| `webkitdirectory` | 사용자가 디렉토리를 선택할 수 있는지 나타내는 불리언 특성. `multiple` 특성을 지정한 경우 복수 선택 가능 |

### `webkitdirectory` 
비표준

`webkitdirectory` 불리언 특성이 존재할 경우 사용자의 파일 선택 창에서 디렉토리만 선택 가능해야 함을 나타냅니다. `HTMLInputElement.webkitdirectory` (en-US) 문서를 방문해 보다 자세한 정보와 예제를 알아보세요.

**참고:** `webkitdirectory`는 원래 WebKit 기반 브라우저에서만 구현했었으나, Microsoft Edge와 Firefox(50 이상)도 지원합니다. 그러나, 비록 상대적으로 널리 지원하고는 있으나, 여전히 비표준 특성이므로 대안이 없는 경우에만 사용해야 합니다.

고유 파일 유형 지정자
------------

**고유 파일 유형 지정자**는 `file` 유형의 `<input>` (en-US)에서 선택할 수 있는 파일의 종류를 설명하는 문자열입니다. 각각의 유형 지정자는 다음 형태 중 하나를 취할 수 있습니다.

* 마침표로 시작하는 유효한 파일 이름 확장자. 대소문자를 구분하지 않습니다. 예시: `.jpg`, `.pdf`, `.doc`.
* 확장자를 포함하지 않은 유효한 MIME 유형 문자열.
* `audio/*`는 "모든 오디오 파일"을 의미합니다.
* `video/*`는 "모든 비디오 파일"을 의미합니다.
* `image/*`는 "모든 이미지 파일"을 의미합니다.

`accept` 특성이 고유 파일 유형 지정자를 값으로 받습니다. 쉼표로 구분하면 여러 개의 지정자도 사용할 수 있습니다. 예를 들어, 표준 이미지 형식 뿐만 아니라 PDF 파일도 받을 수 있어야 하는 입력 칸은 다음 코드처럼 작성할 수 있습니다.


```html
<input type="file" accept="image/\*,.pdf" />
```

파일 입력 칸 사용하기
------------

### 기본 예제


```html
<form method="post" enctype="multipart/form-data">
  <div>
    <label for="file">Choose file to upload</label>
    <input type="file" id="file" name="file" multiple />
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
```


```
div {
  margin-bottom: 10px;
}
```


결과는 다음과 같습니다.

**참고:** 이 예제는 GitHub에서도 볼 수 있습니다. 소스 코드와 라이브 예제를 확인하세요.

사용자의 장치와 운영체제에 상관없이, 파일 입력 칸은 사용자가 파일을 선택할 수 있도록 파일 선택 대화창을 여는 하나의 버튼을 제공합니다.

예제 코드와 같이 `multiple` 특성을 지정한 경우 파일 여러 개를 한 번에 선택할 수 있습니다. 사용자는 플랫폼이 허용하는 방법(`Shift`, `Ctrl` 누르기 등)을 통해 파일 선택 창에서 두 개 이상의 파일을 선택합니다. `<input>` 하나에 파일 하나씩만 선택을 허용하고 싶은 경우 `multiple` 특성을 제거하세요.

### 선택한 파일의 정보 가져오기

요소의 `HTMLInputElement.files` (en-US) 속성은 선택한 파일(`File`) 목록을 `FileList` 객체로 반환합니다. `FileList`는 배열처럼 행동하므로, `length` 속성을 사용해 현재 선택한 파일의 수를 알 수 있습니다.

각각의 `File` 객체는 다음과 같은 정보를 가지고 있습니다.

`name`

파일 이름.

`lastModified`

파일을 마지막으로 수정한 시각을 나타내는 숫자. UNIX 표준시(1970년 1월 1일 자정)으로부터 지난 시간을 밀리초 단위로 나타낸 값입니다.

`lastModifiedDate` 
지원이 중단되었습니다

파일을 마지막으로 수정한 시각을 나타내는 `Date` 객체. 더 이상 사용하지 않아야 합니다. `lastModified`를 대신 사용하세요.

`size`

파일의 크기를 바이트 단위로 나타낸 값.

`type`

파일의 MIME 유형.

`webkitRelativePath` 
비표준

`webkitdirectory` 특성을 사용한 경우, 기준 디렉토리에 대한 파일의 상대적인 경로. 비표준 특성이므로 사용에 주의가 필요합니다.


**Note**: You can set as well as get the value of `HTMLInputElement.files` in all modern browsers; this was most recently added to Firefox, in version 57 (see [Firefox bug 1384030](https://bugzil.la/1384030)).

### 가능한 파일 유형 제한하기

종종, 사용자가 아무 파일이나 선택하지 못하도록 제한하고, 받을 수 있는 파일의 유형을 정해두고 싶을 때가 있습니다. 예를 들어, 프로필 사진을 받는 입력 칸의 경우, JPEG, PNG처럼 웹 호환 가능한 이미지 형식을 선택하도록 해야 할 것입니다.

허용하는 파일 유형은 `accept` 특성을 사용해 지정할 수 있으며, 허용할 파일 확장자나 MIME 유형을 쉼표로 구분한 값을 제공해야 합니다. 다음은 몇 가지 예시입니다.

* `accept="image/png"` or `accept=".png"` — PNG 파일을 허용합니다.
* `accept="image/png, image/jpeg"` 또는 `accept=".png, .jpg, .jpeg"` — PNG와 JPEG를 허용합니다.
* `accept="image/*"` — `image/*` MIME 유형을 가진 모든 파일을 허용합니다. 많은 모바일 기기에서는, 이 값을 지정할 경우 사용자가 카메라로 사진을 찍을 수 있도록 설정합니다.
* `accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"` — MS Word 문서처럼 보이는 파일을 모두 허용합니다.

보다 완전한 예제 코드를 보겠습니다.


```html
<form method="post" enctype="multipart/form-data">
  <div>
    <label for="profile\_pic">Choose file to upload</label>
    <input
 type="file"
 id="profile\_pic"
 name="profile\_pic"
 accept=".jpg, .jpeg, .png" />
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
```


```
div {
  margin-bottom: 10px;
}
```


위 코드는 이전 예제와 비슷하게 보이는 결과를 냅니다.

**참고:** GitHub에서도 볼 수 있습니다. 소스 코드, 라이브 실행 결과.

외형은 유사해 보일지라도, 이번 예제에서 파일을 선택하려고 한다면 `accept`에 지정한 파일 유형만 선택 가능함을 확인할 수 있습니다. (정확한 동작은 브라우저와 운영체제에 따라 다를 수 있습니다)

![Screenshot of a macOS file picker dialog. Files other than JPEG are grayed-out and unselectable.](/ko/docs/Web/HTML/Element/input/file/file-chooser.png)

`accept` 특성은 선택한 파일 유형을 검증하지는 않으며, 단순히 브라우저가 사용자를 올바른 파일 유형으로 유도하도록 힌트를 제공할 뿐입니다. (대부분의 경우) 사용자가 파일 선택 창의 옵션을 설정해 `accept`를 덮어쓰고 자신이 원하는 아무 파일이나 선택할 수 있으므로, 파일 입력 칸에 잘못된 유형의 파일이 올 수 있습니다.

그러므로, 반드시 적절한 서버 사이드 유효성 검증을 통해 `accept` 특성을 보조해야 합니다.

### 참고

1. 파일 입력 칸의 값을 스크립트에서 설정할 수는 없습니다. 따라서 다음 코드는 아무런 효과도 내지 않습니다.

```js
const input = document.querySelector("input[type=file]");
input.value = "foo";
```

2. `<input type="file">` 로 선택한 원본 파일의 실제 경로는 명확한 보안상 문제로 인해 알 수 없습니다. 대신 앞에 `C:\fakepath\` 를 붙인 파일 이름을 경로로 보여줍니다. 하필 이런 모습이 된 것에는 역사적인 이유가 있지만 이 동작은 모든 최신 브라우저에서 지원하고 있으며, 사실 명세에도 포함되어 있습니다.
예제
--

이번 예제에서는 좀 더 발전된 파일 선책 창을 만들어 보겠습니다. `HTMLInputElement.files` 속성에서 알 수 있는 정보도 활용하면서, 몇 가지 재밌는 활용법도 보여드리겠습니다.

**참고:** 전체 소스 코드는 GitHub에 있습니다. file-example.html (라이브 실행 결과). 주 목적이 JavaScript이므로 CSS는 따로 설명하지 않겠습니다.

우선 HTML을 살펴보겠습니다.


```html
<form method="post" enctype="multipart/form-data">
  <div>
    <label for="image\_uploads">Choose images to upload (PNG, JPG)</label>
    <input
 type="file"
 id="image\_uploads"
 name="image\_uploads"
 accept=".jpg, .jpeg, .png"
 multiple />
  </div>
  <div class="preview">
    <p>No files currently selected for upload</p>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
```


```
html {
  font-family: sans-serif;
}

form {
  width: 580px;
  background: #ccc;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid black;
}

form ol {
  padding-left: 0;
}

form li,
div > p {
  background: #eee;
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
  list-style-type: none;
  border: 1px solid black;
}

form img {
  height: 64px;
  order: 1;
}

form p {
  line-height: 32px;
  padding-left: 10px;
}

form label,
form button {
  background-color: #7f9ccb;
  padding: 5px 10px;
  border-radius: 5px;
  border: 1px ridge black;
  font-size: 0.8rem;
  height: auto;
}

form label:hover,
form button:hover {
  background-color: #2d5ba3;
  color: white;
}

form label:active,
form button:active {
  background-color: #0d3f8f;
  color: white;
}
```


지금까지 봤던 것과 거의 같으므로 설명할 부분은 없겠습니다.

이제 JavaScript 차례입니다.

우선 양식의 파일 입력 칸과, `.preview` 클래스를 가진 `<div>` (en-US) 요소에 대한 참조를 가져옵니다. 그 후, `<input>` (en-US) 요소를 숨겨버립니다. 파일 입력 칸은 보통 못생겼고, 스타일을 적용하기도 어려우며 브라우저마다 디자인이 다르기 때문입니다. `<input>`은 연결된 `<label>`을 클릭해도 활성화할 수 있으므로, 시각적으로 `<input>`을 숨긴 후 레이블에 버튼처럼 스타일을 적용해서, 파일을 업로드하고 싶은 경우 레이블을 누르라는 것을 알려주는 편이 낫습니다.


```js
var input = document.querySelector("input");
var preview = document.querySelector(".preview");

input.style.opacity = 0;
```


**참고:** `visibility: hidden`, `display: none` (en-US)로 숨길 경우 접근성 보조 기술이 파일 입력 칸을 상호작용 할 수 없는 상태라고 인식하기 때문에 `opacity`를 대신 사용합니다.

그 다음으로는 입력 칸에 이벤트 수신기를 부착해 그 값이 달라지는지(예제의 경우, 파일을 선택할 때) 지켜봅니다. 이벤트 수신기는 밑에서 만들 `updateImageDisplay()` 함수를 호출하게 됩니다.


```js
input.addEventListener("change", updateImageDisplay);
```


`updateImageDisplay()` 함수를 호출하면 다음 작업을 수행하게 됩니다.

* `while` 반복문을 사용해 `<div>`에 존재하는 이전 파일의 미리보기를 제거합니다.
* 선택한 모든 파일의 정보를 들고 있는 `FileList` 객체를 가져온 후 `curFiles` 변수에 저장합니다.
* `curFiles.length`가 0과 같은지 검사해 아무런 파일도 선택하지 않았는지 검사합니다. 그렇다면, `<div>`에 아무런 파일도 선택하지 않았다는 메시지를 출력합니다.
* 반면, 파일을 선택한 경우라면, 각각의 파일을 순회하며 각각의 정보를 미리보기 `<div>`에 출력합니다. 참고할 점:
* 뒤에서 작성할 `validFileType()` 함수를 사용해 순회 중인 파일이 올바른 유형, 즉 `accept` 특성에 속한 파일인지 판별합니다.
* 올바른 파일이라면,
    + `<div>` 안의 목록에 해당 파일의 이름과 크기를 항목으로 추가합니다. 이름은 `file.name`과 `file.size`로 가져옵니다. 또 다른 함수인 `returnFileSize()`는 파일 크기를 보기 좋게 바이트/KB/MB로 서식해 출력합니다. (브라우저는 바이트 크기로만 알려줍니다)
    + `URL.createObjectURL(curFiles[i])`를 호출해 이미지 미리보기 썸네일을 생성하고, 새로 만든 `<img>` 태그의 `src`에 지정한 후, 이미지도 목록의 항목에 추가합니다.
* 파일 유형이 유효하지 않은 경우 사용자에게 다른 파일을 선택해야 한다고 알려주는 메시지를 표시합니다.


```js
function updateImageDisplay() {
  while (preview.firstChild) {
    preview.removeChild(preview.firstChild);
  }

  const curFiles = input.files;
  if (curFiles.length === 0) {
    const para = document.createElement("p");
    para.textContent = "No files currently selected for upload";
    preview.appendChild(para);
  } else {
    const list = document.createElement("ol");
    preview.appendChild(list);

    for (const file of curFiles) {
      const listItem = document.createElement("li");
      const para = document.createElement("p");
      if (validFileType(file)) {
        para.textContent = `File name ${file.name}, file size ${returnFileSize(
 file.size,
 )}.`;
        const image = document.createElement("img");
        image.src = URL.createObjectURL(file);

        listItem.appendChild(image);
        listItem.appendChild(para);
      } else {
        para.textContent = `File name ${file.name}: Not a valid file type. Update your selection.`;
        listItem.appendChild(para);
      }

      list.appendChild(listItem);
    }
  }
}
```


`validFileType()` 함수는 매개변수로 `File` 객체를 받아서, 그 파일의 `type`이 `fileTypes`의 아무 값과 동일한지 판별합니다. `Array.prototype.includes()`를 사용하여 type과 일치하는 값이 존재하면 `true`, 아니면 `false`를 반환합니다.


```js
// https://developer.mozilla.org/ko/docs/Web/Media/Formats/Image\_types
const fileTypes = [
  "image/apng",
  "image/bmp",
  "image/gif",
  "image/jpeg",
  "image/pjpeg",
  "image/png",
  "image/svg+xml",
  "image/tiff",
  "image/webp",
  "image/x-icon",
];

function validFileType(file) {
  return fileTypes.includes(file.type);
}
```


`returnFileSize()` 함수는 숫자(현재 파일의 `size` 속성에서 가져온, 파일의 바이트 크기)를 받은 후, 읽기 좋게 바이트/KB/MB 단위로 서식을 적용합니다.


```js
function returnFileSize(number) {
  if (number < 1024) {
    return number + "bytes";
  } else if (number >= 1024 && number < 1048576) {
    return (number / 1024).toFixed(1) + "KB";
  } else if (number >= 1048576) {
    return (number / 1048576).toFixed(1) + "MB";
  }
}
```


결과는 다음과 같습니다. 한번 직접 파일을 선택해보세요.

명세
--

| Specification |
| --- |
| HTML Standard # file-upload-state-(type=file) |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보 기
------

* 웹 애플리케이션에서 파일 사용하기 — `<input type="file">`과 File API에 대한 유용한 예제를 더 가지고 있습니다.
* CSS 속성 호환성 (en-US)