©
Dieses Dokument verwendet PHP-Handbuch für chinesische Websites Freigeben
<input>
元素type="file"
让用户选择一个或多个文件,通过表单提交上传到服务器,或者通过 JavaScript 使用File API进行操作。
<input name="myFile" type="file">
值 | 表示所选文件路径的DOMString。 |
---|---|
活动 | 改变和输入 |
支持的通用属性 | 接受,多重,必需 |
IDL属性 | 文件和价值 |
方法 | 选择() |
“文件输入” value
属性包含一个DOMString
表示所选文件的路径。
注意:
如果选择多个文件,则该字符串表示第一个选定的文件。JavaScript 可以通过输入的访问其他文件FileList
属性(https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Getting_information_about_selected_file(S 29%)。
如果尚未选择文件,则该字符串为""
(空)。
该字符串前缀C:\fakepath\
为了防止恶意软件猜测用户的文件结构。
<form> <div> <label for="file">Choose file to upload</label> <input type="file" id="file" name="file" multiple> </div> <div> <button>Submit</button> </div></form>
这会产生以下输出:
注意:你也可以在 GitHub 上找到这个例子 - 查看源代码,也可以看到它在线运行。
无论用户的设备或操作系统如何,文件输入都会提供一个按钮,用于打开允许用户选择文件的文件选择器对话框。
multiple
如上所示,包含属性指定可以一次选择多个文件。用户可以用他们选择的平台允许的任何方式从文件选择器中选择多个文件(例如按住Shift或Control,然后单击)。如果您只希望用户每次选择一个文件<input>
,则省略该multiple
属性。
提交示例时,每个选定文件的名称将按以下方式添加到 URL 参数中: ?file=file1.txt&file=file2.txt
所选文件'由元素的HTMLInputElement.files
属性返回 - 返回一个FileList
包含File
对象列表的对象。该FileList
像一个数组的行为,所以你可以检查其length
属性来获取选定文件的数量。
每个File
对象都包含以下信息:
name
:文件名称。
lastModified
:表示文件上次修改日期的数字,作为 UNIX 时间戳记。
lastModifiedDate
:Date
表示文件上次修改日期和时间的对象。
size
:代表文件大小的数字(以字节为单位)。
type
:DOMString
表示文件的MIME类型。
注意:您可以设置以及HTMLInputElement.files
在所有现代浏览器中获得它的价值- 这是最新版本添加到
Firefox 的版本57(见错误1384030)。
通常你不会想要任何类型的文件。例如,如果您的文件输入允许用户上传个人资料图片,那么您可能希望他们选择与网络兼容的图片格式,例如 JPEG 或 PNG 。
可以使用accept
属性指定可接受的文件类型,该属性采用允许的文件扩展名或 MIME 类型的逗号分隔列表。一些例子:
accept="image/png"
或者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 文档的东西。
让我们看起来像一个更完整的例子:
<form> <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>
这产生了与前面的例子类似的输出:
注意:你也可以在 GitHub 上找到这个例子 - 查看源代码,也可以看到它在线运行。
它可能看起来很相似,但如果您尝试选择带有此输入的文件,则会看到文件选取器只允许您选择accept
值中指定的文件类型(确切性质因浏览器和操作系统而异)。
accept
属性不会验证所选文件的类型 - 它为浏览器提供了一些提示,以指导用户选择正确的文件类型。用户仍然可以(在大多数情况下)在文件选择器中切换选项,以使所有文件可选,然后选择不正确的文件类型。
因此,请确保该accept
属性由适当的服务器端验证进行备份。
在这个例子中,我们将展示一个稍微更高级的文件选择器,它利用了该HTMLInputElement.files
属性中可用的文件信息,并展示了一些聪明的技巧。
注意:你可以在 GitHub - file-example.html上看到这个例子的完整源代码。我们不会解释 CSS ; JavaScript 是主要焦点。
首先,让我们看看 HTML:
<form> <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>
这与我们以前见过的相似 - 没有什么特别的评论。
接下来,我们来看看 JavaScript 。
在脚本的第一行中,我们获得对表单输入本身的引用,以及<div>
具有类的元素.preview
。接下来,我们隐藏了这个<input>
元素 - 我们这样做是因为文件输入在浏览器的设计中往往是丑陋,难以设计风格以及不一致。您可以通过单击它来激活输入元素<label>
,因此最好直观地隐藏输入并像标签一样设置按钮的样式,以便用户如果想要上传文件就知道要与之交互。
var input = document.querySelector('input');var preview = document.querySelector('.preview');input.style.opacity = 0;
注意: opacity
用于隐藏文件输入而不是visibility: hidden
或display: none
,因为辅助技术将后两种样式解释为文件输入不是交互式的。
接下来,我们添加一个事件监听器到输入中,当它的选择值改变时(在这种情况下,当文件被选中时)。事件监听器调用我们的自定义updateImageDisplay()
函数。
input.addEventListener('change', updateImageDisplay);
每当updateImageDisplay()
函数被调用时,我们:
使用while
循环清空预览的前一个内容<div>
。
抓取FileList
包含所有选定文件信息的对象,并将其存储在名为的变量中curFiles
。
通过检查是否curFiles.length
等于0 来检查是否未选择文件。如果是,则在预览中输出一条消息,<div>
指出没有选择任何文件。
如果文件已被选中,我们遍历每个人,打印有关它的信息到预览<div>
。这里需要注意的事项:
我们使用自定义validFileType()
函数来检查文件是否具有正确的类型(例如accept
属性中指定的图像类型)。
如果是,我们:
将其名称和文件大小打印到上一个列表项中<div>
(从curFiles[i].name
and 获得curFiles[i].size
)。自定义returnFileSize()
函数以字节/ KB / MB返回格式良好的版本(默认情况下,浏览器以绝对字节报告大小)。
通过调用 CSS 并缩小图像大小来生成图像的缩略图预览,然后将该图像插入到列表项中。window.
URL.createObjectURL
(curFiles[i])
如果文件类型无效,我们会在列表项中显示一条消息,告诉用户他们需要选择不同的文件类型。
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 < 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); } }}
自定义validFileType()
函数将File
对象作为参数,然后遍历允许的文件类型列表,检查是否有任何文件的type
属性匹配。如果找到匹配项,则函数返回true
。如果找不到匹配,则返回false
。
var fileTypes = [ 'image/jpeg', 'image/pjpeg', 'image/png']function validFileType(file) { for(var i = 0; i < fileTypes.length; i++) { if(file.type === fileTypes[i]) { return true; } } return false;}
returnFileSize()
函数需要一个数字(取自当前文件size
属性的字节数),并将其转换为格式良好的大小(以字节/ KB / MB为单位)。
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'; }}
这个例子看起来像这样 - 试一试:
规范 | 状态 | 评论 |
---|---|---|
HTML Living Standard该规范中的<input type =“file”>“的定义。 | 生活水平 | 初始定义 |
HTML 5.1该规范中的<input type =“file”>“的定义。 | 建议 | 初始定义 |
Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 1.0 | ? | 1.0 (1.7 or earlier) | (Yes) | 1.0 | 1.0 |
Feature | Android | Chrome for Android | Edge | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | iOS WebKit (Safari/Chrome/Firefox/etc) |
---|---|---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | (Yes) | 4.0 (4.0) | (Yes) | (Yes) | (Yes) |