aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/html/element/input/file/index.html
blob: f14893552c22e6e4df7b323363bcb316914866ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
---
title: <input type="file">
slug: Web/HTML/Element/Input/file
translation_of: Web/HTML/Element/input/file
---
<div>{{HTMLRef}}</div>

<p><span class="seoSummary">{{HTMLElement("input")}} элемент с атрибутом <strong><code>type="file"</code></strong> позволяет пользователю выбрать один файл или более из файлового хранилища своего устройства. После выбора эти файлы могут быть загружены на сервер при помощи <a href="/ru/docs/Learn/HTML/Forms">формы</a>, или обработаны JavaScript и <a href="/en-US/docs/Using_files_from_web_applications">File API</a>.</span></p>

<div id="file-example">
<pre class="brush: html">&lt;input name="myFile" type="file"&gt;
</pre>
</div>

<p>{{EmbedLiveSample('file-example', 650, 40)}}</p>

<table class="properties">
 <tbody>
  <tr>
   <td><strong>{{anch("Value")}}</strong></td>
   <td>{{domxref("DOMString")}} представляет собой путь до выбранного файла.</td>
  </tr>
  <tr>
   <td><strong>Действия</strong></td>
   <td>{{event("change")}} и{{event("input")}}</td>
  </tr>
  <tr>
   <td><strong>Поддерживаемые атрибуты</strong></td>
   <td>{{htmlattrxref("accept", "input")}}, {{htmlattrxref("multiple", "input")}}, {{htmlattrxref("required", "input")}}</td>
  </tr>
  <tr>
   <td><strong>IDL атрибуты</strong></td>
   <td><code>files</code> and <code>value</code></td>
  </tr>
  <tr>
   <td><strong>Методы</strong></td>
   <td>{{domxref("HTMLInputElement.select", "select()")}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Value">Value</h2>

<p>Атрибут {{htmlattrxref("value", "input")}} элемента input содержит {{domxref("DOMString")}}, который представляет путь к выбранным файлам. Если пользователь выбрал несколько файлов, <code>value</code> представляет первый файл из списка. Остальные файлы можно определить используя {{domxref("HTMLInputElement.files")}} свойство элемента input.</p>

<div class="note"><strong>Note:</strong>

<ol>
 <li>Если выбрано несколько файлов, строка представляет собой первый выбранный файл. JavaScript предоставляет доступ к остальным файлам через свойство <a href="/en-US/docs/Using_files_from_web_applications#Getting_information_about_selected_file(s)"><code>FileList</code></a>.</li>
 <li>Если не выбрано ни одного файла, .строка равна <code>""</code> (пустая).</li>
 <li>Строка <a href="https://html.spec.whatwg.org/multipage/input.html#fakepath-srsly">начинается с  <code>C:\fakepath\</code></a>,  для предотвращения определения файловой структуры пользователя вредоносным ПО.</li>
</ol>
</div>

<h2 id="Additional_attributes">Additional attributes</h2>

<p>In addition to the common attributes shared by all {{HTMLElement("input")}} elements, inputs of type <code>file</code> also support:</p>

<dl>
 <dt><code>files</code></dt>
 <dd>A {{domxref("FileList")}} object that lists every selected file. This list has no more than one member unless the {{htmlattrxref("multiple", "input")}} attribute is specified.</dd>
</dl>

<h2 id="Using_file_inputs">Using file inputs</h2>

<h3 id="A_basic_example">A basic example</h3>

<pre class="brush: html">&lt;form method="post" enctype="multipart/form-data"&gt;
 &lt;div&gt;
   &lt;label for="file"&gt;Choose file to upload&lt;/label&gt;
   &lt;input type="file" id="file" name="file" multiple&gt;
 &lt;/div&gt;
 &lt;div&gt;
   &lt;button&gt;Submit&lt;/button&gt;
 &lt;/div&gt;
&lt;/form&gt;</pre>

<div class="hidden">
<pre class="brush: css">div {
  margin-bottom: 10px;
}</pre>
</div>

<p>This produces the following output:</p>

<p>{{EmbedLiveSample('A_basic_example', 650, 60)}}</p>

<div class="note">
<p><strong>Note</strong>: You can find this example on GitHub too — see the <a href="https://github.com/mdn/learning-area/blob/master/html/forms/file-examples/simple-file.html">source code</a>, and also <a href="https://mdn.github.io/learning-area/html/forms/file-examples/simple-file.html">see it running live</a>.</p>
</div>

<p>Regardless of the user's device or operating system, the file input provides a button that opens up a file picker dialog that allows the user to choose a file.</p>

<p>Including the {{htmlattrxref("multiple", "input")}} attribute, as shown above, specifies that multiple files can be chosen at once. The user can choose multiple files from the file picker in any way that their chosen platform allows (e.g. by holding down <kbd>Shift</kbd> or <kbd>Control</kbd>, and then clicking). If you only want the user to choose a single file per <code>&lt;input&gt;</code>, omit the <code>multiple</code> attribute.</p>

<p>When the form is submitted, each selected file's name will be added to URL parameters in the following fashion: <code>?file=file1.txt&amp;file=file2.txt</code></p>

<h3 id="Getting_information_on_selected_files">Getting information on selected files</h3>

<p>The selected files' are returned by the element's {{domxref("HTMLElement.files", "files")}} property, which is a {{domxref("FileList")}} object containing a list of {{domxref("File")}} objects. The <code>FileList</code> behaves like an array, so you can check its <code>length</code> property to get the number of selected files.</p>

<p>Each <code>File</code> object contains the following information:</p>

<dl>
 <dt><code>name</code></dt>
 <dd>The file's name.</dd>
 <dt><code>lastModified</code></dt>
 <dd>A number specifying the date and time at which the file was last modified, in milliseconds since the UNIX epoch (January 1, 1970 at midnight).</dd>
 <dt><code>lastModifiedDate</code> {{deprecated_inline}}</dt>
 <dd>A {{jsxref("Date")}} object representing the date and time at which the file was last modified. <em>This is deprecated and should not be used. Use <code>lastModified</code> instead.</em></dd>
 <dt><code>size</code></dt>
 <dd>The size of the file in bytes.</dd>
 <dt><code>type</code></dt>
 <dd>The file's <a href="/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types">MIME type</a>.</dd>
 <dt>webkitRelativePath {{non-standard_inline}}</dt>
 <dd>A string specifying the file's path relative to the base directory selected in a directory picker (that is, a <code>file</code> picker in which the {{htmlattrxref("webkitdirectory", "input")}} attribute is set). <em>This is non-standard and should be used with caution.</em></dd>
</dl>

<div class="note">
<p><strong>Note</strong>: You can set as well as get the value of <code>HTMLInputElement.files</code> in all modern browsers; this was most recently added to Firefox, in version 57 (see {{bug(1384030)}}).</p>
</div>

<h3 id="Limiting_accepted_file_types">Limiting accepted file types</h3>

<p>Often you won't want the user to be able to pick any arbitrary type of file; instead, you often want them to select files of a specific type or types. For example, if your file input lets users upload a profile picture, you probably want them to select web-compatible image formats, such as <a href="/en-US/docs/Glossary/jpeg">JPEG</a> or <a href="/en-US/docs/Glossary/PNG">PNG</a>.</p>

<p>Acceptable file types can be specified with the {{htmlattrxref("accept","input")}} attribute, which takes a comma-separated list of allowed file extensions or MIME types. Some examples:</p>

<ul>
 <li><code>accept="image/png"</code> or <code>accept=".png"</code> — Accepts PNG files.</li>
 <li><code>accept="image/png, image/jpeg"</code> or <code>accept=".png, .jpg, .jpeg"</code> — Accept PNG or JPEG files.</li>
 <li><code>accept="image/*"</code> — Accept any file with an <code>image/*</code> MIME type. (Many mobile devices also let the user take a picture with the camera when this is used.)</li>
 <li><code>accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"</code> — accept anything that smells like an MS Word document.</li>
</ul>

<p>Let's look like a more complete example:</p>

<pre class="brush: html">&lt;form method="post" enctype="multipart/form-data"&gt;
  &lt;div&gt;
    &lt;label for="profile_pic"&gt;Choose file to upload&lt;/label&gt;
    &lt;input type="file" id="profile_pic" name="profile_pic"
          accept=".jpg, .jpeg, .png"&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;button&gt;Submit&lt;/button&gt;
  &lt;/div&gt;
&lt;/form&gt;</pre>

<div class="hidden">
<pre class="brush: css">div {
  margin-bottom: 10px;
}</pre>
</div>

<p>This produces a similar-looking output to the previous example:</p>

<p>{{EmbedLiveSample('Limiting_accepted_file_types', 650, 60)}}</p>

<div class="note">
<p><strong>Note</strong>: You can find this example on GitHub too — see the <a href="https://github.com/mdn/learning-area/blob/master/html/forms/file-examples/file-with-accept.html">source code</a>, and also <a href="https://mdn.github.io/learning-area/html/forms/file-examples/file-with-accept.html">see it running live</a>.</p>
</div>

<p>It may look similar, but if you try selecting a file with this input, you'll see that the file picker only lets you select the file types specified in the <code>accept</code> value (the exact nature differs across browsers and operating systems).</p>

<p><img alt="Screenshot of a macOS file picker dialog. Files other than JPEG are grayed-out and unselectable." src="https://mdn.mozillademos.org/files/15183/file-chooser.png" style="margin: 0 auto;"></p>

<p>The <code>accept</code> attribute doesn't validate the types of the selected files; it simply provides hints for browsers to guide users towards selecting the correct file types. It is still possible (in most cases) for users to toggle an option in the file chooser that makes it possible to override this and select any file they wish, and then choose incorrect file types.</p>

<p>Because of this, you should make sure that the <code>accept</code> attribute is backed up by appropriate server-side validation.</p>

<h2 id="Examples">Examples</h2>

<p>In this example, we'll present a slightly more advanced file chooser that takes advantage of the file information available in the {{domxref("HTMLInputElement.files")}} property, as well as showing off a few clever tricks.</p>

<div class="note">
<p><strong>Note</strong>: You can see the complete source code for this example on GitHub — <a href="https://github.com/mdn/learning-area/blob/master/html/forms/file-examples/file-example.html">file-example.html</a> (<a href="https://mdn.github.io/learning-area/html/forms/file-examples/file-example.html">see it live also</a>). We won't explain the CSS; the JavaScript is the main focus.</p>
</div>

<p>First of all, let's look at the HTML:</p>

<pre class="brush: html">&lt;form method="post" enctype="multipart/form-data"&gt;
  &lt;div&gt;
    &lt;label for="image_uploads"&gt;Choose images to upload (PNG, JPG)&lt;/label&gt;
    &lt;input type="file" id="image_uploads" name="image_uploads" accept=".jpg, .jpeg, .png" multiple&gt;
  &lt;/div&gt;
  &lt;div class="preview"&gt;
    &lt;p&gt;No files currently selected for upload&lt;/p&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;button&gt;Submit&lt;/button&gt;
  &lt;/div&gt;
&lt;/form&gt;</pre>

<div class="hidden">
<pre class="brush: css">html {
  font-family: sans-serif;
}

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

form ol {
  padding-left: 0;
}

form li, div &gt; 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;
}</pre>
</div>

<p>This is similar to what we've seen before — nothing special to comment on.</p>

<p>Next, let's walk through the JavaScript.</p>

<p>In the first lines of script, we get references to the form input itself, and the {{htmlelement("div")}} element with the class of <code>.preview</code>. Next, we hide the {{htmlelement("input")}} element — we do this because file inputs tend to be ugly, difficult to style, and inconsistent in their design across browsers. You can activate the input element by clicking its {{htmlelement("label")}}, so it is better to visually hide the input and style the label like a button, so the user will know to interact with it if they want to upload files.</p>

<pre class="brush: js">var input = document.querySelector('input');
var preview = document.querySelector('.preview');

input.style.opacity = 0;</pre>

<div class="note">
<p><strong>Note:</strong> <a href="/en-US/docs/Web/CSS/opacity"><code>opacity</code></a> is used to hide the file input instead of <a href="/en-US/docs/Web/CSS/visibility"><code>visibility: hidden</code></a> or <a href="/en-US/docs/Web/CSS/display"><code>display: none</code></a>, because assistive technology interprets the latter two styles to mean the file input isn't interactive.</p>
</div>

<p>Next, we add an <a href="/en-US/docs/Web/API/EventTarget/addEventListener">event listener</a> to the input to listen for changes to its selected value changes (in this case, when files are selected). The event listener invokes our custom <code>updateImageDisplay()</code> function.</p>

<pre class="brush: js">input.addEventListener('change', updateImageDisplay);</pre>

<p>Whenever the <code>updateImageDisplay()</code> function is invoked, we:</p>

<ul>
 <li>Use a <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a></code> loop to empty the previous contents of the preview <code>&lt;div&gt;</code>.</li>
 <li>Grab the {{domxref("FileList")}} object that contains the information on all the selected files, and store it in a variable called <code>curFiles</code>.</li>
 <li>Check to see if no files were selected, by checking if<code>curFiles.length</code> is equal to 0. If so, print a message into the preview <code>&lt;div&gt;</code> stating that no files have been selected.</li>
 <li>If files <em>have</em> been selected, we loop through each one, printing information about it into the preview <code>&lt;div&gt;</code>. Things to note here:</li>
 <li>We use the custom <code>validFileType()</code> function to check whether the file is of the correct type (e.g. the image types specified in the <code>accept</code> attribute).</li>
 <li>If it is, we:
  <ul>
   <li>Print out its name and file size into a list item inside the previous <code>&lt;div&gt;</code> (obtained from <code>curFiles[i].name</code> and <code>curFiles[i].size</code>). The custom <code>returnFileSize()</code> function returns a nicely-formatted version of the size in bytes/KB/MB (by default the browser reports the size in absolute bytes).</li>
   <li>Generate a thumbnail preview of the image by calling <code>window.<a href="/en-US/docs/Web/API/URL/createObjectURL">URL.createObjectURL</a>(curFiles[i])</code> and reducing the image size in the CSS, then insert that image into the list item too.</li>
  </ul>
 </li>
 <li>If the file type is invalid, we display a message inside a list item telling the user that they need to select a different file type.</li>
</ul>

<pre class="brush: js">function updateImageDisplay() {
  while(preview.firstChild) {
    preview.removeChild(preview.firstChild);
  }

  var curFiles = input.files;
  if(curFiles.length === 0) {
    var para = document.createElement('p');
    para.textContent = 'No files currently selected for upload';
    preview.appendChild(para);
  } else {
    var list = document.createElement('ol');
    preview.appendChild(list);
    for(var i = 0; i &lt; curFiles.length; i++) {
      var listItem = document.createElement('li');
      var para = document.createElement('p');
      if(validFileType(curFiles[i])) {
        para.textContent = 'File name ' + curFiles[i].name + ', file size ' + returnFileSize(curFiles[i].size) + '.';
        var image = document.createElement('img');
        image.src = window.URL.createObjectURL(curFiles[i]);

        listItem.appendChild(image);
        listItem.appendChild(para);

      } else {
        para.textContent = 'File name ' + curFiles[i].name + ': Not a valid file type. Update your selection.';
        listItem.appendChild(para);
      }

      list.appendChild(listItem);
    }
  }
}</pre>

<p>The custom <code>validFileType()</code> function takes a {{domxref("File")}} object as a parameter, then loops through the list of allowed file types, checking if any matches the file's <code>type</code> property. If a match is found, the function returns <code>true</code>. If no match is found, it returns <code>false</code>.</p>

<pre class="brush: js">var fileTypes = [
  'image/jpeg',
  'image/pjpeg',
  'image/png'
]

function validFileType(file) {
  for(var i = 0; i &lt; fileTypes.length; i++) {
    if(file.type === fileTypes[i]) {
      return true;
    }
  }

  return false;
}</pre>

<p>The <code>returnFileSize()</code> function takes a number (of bytes, taken from the current file's <code>size</code> property), and turns it into a nicely formatted size in bytes/KB/MB.</p>

<pre class="brush: js">function returnFileSize(number) {
  if(number &lt; 1024) {
    return number + 'bytes';
  } else if(number &gt; 1024 &amp;&amp; number &lt; 1048576) {
    return (number/1024).toFixed(1) + 'KB';
  } else if(number &gt; 1048576) {
    return (number/1048576).toFixed(1) + 'MB';
  }
}</pre>

<p>The example looks like this; have a play:</p>

<p>{{EmbedLiveSample('Examples', '100%', 200)}}</p>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('HTML WHATWG', 'input.html#file-upload-state-(type=file)', '&lt;input type="file"&gt;')}}</td>
   <td>{{Spec2('HTML WHATWG')}}</td>
   <td>Initial definition</td>
  </tr>
  <tr>
   <td>{{SpecName('HTML5.1', 'sec-forms.html#file-upload-state-typefile', '&lt;input type="file"&gt;')}}</td>
   <td>{{Spec2('HTML5.1')}}</td>
   <td>Initial definition</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p>{{Compat("html.elements.input.input-file")}}</p>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="/en-US/docs/Using_files_from_web_applications">Using files from web applications</a> — contains a number of other useful examples related to <code>&lt;input type="file"&gt;</code> and the <a href="/en-US/docs/Web/API/File">File API</a>.</li>
</ul>