Javascript 如何从输入文件控件中删除一个特定的选定文件
如何从输入文件控件中删除一个特定的选定文件 我有一个输入文件控件,可以选择多个文件;但是,我想验证一个文件,如果它有一个错误的扩展名,那么我应该从文件控件本身删除该文件,这可能吗 我试了如下Javascript 如何从输入文件控件中删除一个特定的选定文件,javascript,jquery,file-upload,multifile,Javascript,Jquery,File Upload,Multifile,如何从输入文件控件中删除一个特定的选定文件 我有一个输入文件控件,可以选择多个文件;但是,我想验证一个文件,如果它有一个错误的扩展名,那么我应该从文件控件本身删除该文件,这可能吗 我试了如下 <input type="file" name="fileToUpload" id="fileToUpload" multiple/> <script> $("#fileToUpload")[0].files[0] </script> 下面是该对象的屏幕截图,但我无
<input type="file" name="fileToUpload" id="fileToUpload" multiple/>
<script> $("#fileToUpload")[0].files[0] </script>
下面是该对象的屏幕截图,但我无法修改它
正如其他人指出的,它是只读的。不过,您可以通过将这些文件放入一个单独的数组来解决这个问题。然后,你可以用这个精心策划的文件列表做任何你想做的事情。如果目标是将它们上载到服务器,则可以使用API 下面是一种完全避免修改文件列表的方法。 步骤: 添加普通文件输入更改事件侦听器 循环通过更改事件中的每个文件,筛选所需的验证 将有效文件推送到单独的数组中 使用FileReader API在本地读取文件 将已处理的有效文件提交到服务器 事件处理程序和基本文件循环代码:
var validatedFiles = [];
$("#fileToUpload").on("change", function (event) {
var files = event.originalEvent.target.files;
files.forEach(function (file) {
if (file.name.matches(/something.txt/)) {
validatedFiles.push(file); // Simplest case
} else {
/* do something else */
}
});
});
下面是一个更复杂的文件循环版本,它显示了如何使用FileReader API将文件加载到浏览器中,并可以选择将其作为Base64编码的blob提交到服务器
files.forEach(function (file) {
if (file.name.matches(/something.txt/)) { // You could also do more complicated validation after processing the file client side
var reader = new FileReader();
// Setup listener
reader.onload = (function (processedFile) {
return function (e) {
var fileData = { name : processedFile.name, fileData : e.target.result };
// Submit individual file to server
$.post("/your/url/here", fileData);
// or add to list to submit as group later
validatedFiles.push(fileData);
};
})(file);
// Process file
reader.readAsDataURL(file);
} else {
/* still do something else */
}
});
关于使用FileReader API的注意事项。Base64编码文件将使其大小增加约30%。如果这是不可接受的,您需要尝试其他方法。html
<input id="fileInput" name="fileInput" type="file" />
<input onclick="clearFileInput()" type="button" value="Clear" />
我想我也应该在这里加上我的评论,我在这里回答: 我找到了一个解决办法。这根本不需要AJAX来处理请求,表单可以发送到服务器。基本上,您可以创建一个隐藏或文本输入,并将其value属性设置为处理所选文件后创建的base64字符串
<input type=hidden value=${base64string} />
您可能会考虑创建多个输入文件,而不是输入文本或隐藏。这将不起作用,因为我们无法为其赋值
此方法将在发送到数据库的数据中包含输入文件,若要忽略输入文件,可以: 在后端不要考虑领域; 在序列化表单之前,可以将禁用属性设置为输入文件; 在发送数据之前删除DOM元素。 当您想要删除一个文件时,只需获取元素的索引,并从DOM中删除输入元素文本或隐藏内容 要求: 您需要编写逻辑来转换base64中的文件,并在输入文件触发更改事件时将所有文件存储在一个数组中。 优点: 这基本上会给你很多控制,你可以过滤,比较文件,检查文件大小,MIME类型,等等。。我知道这是一个老帖子,但我已经花了很多时间试图解决这个问题,所以我将发布我的解决方案。有一种方法可以使用另一个文件列表更新fileField元素的文件列表-这可以通过数据传输完成:
let updateFileList = function (fileField, index) {
let fileBuffer = Array.from(fileField.files);
fileBuffer.splice(index, 1);
/** Code from: https://stackoverflow.com/a/47172409/8145428 */
const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
for (let file of fileBuffer) { dT.items.add(file); }
fileField.files = dT.files;
}
上面的函数将fileField作为DOM对象,并在fileField的fileList中删除文件的索引,并相应地更新传递的fileField
希望这能为其他人节省一些时间
你打算怎么处理这些文件?一旦用户上传它们,它们就被复制到你的tmp文件夹中,并且它们的信息保存在你的数组中,因此当你处理它们时,只需跳过任何扩展名错误的文件…伙计们,它不是数组,它是一个具有属性0,1,2的对象,因此我无法在此执行数组操作不幸的是,你无法修改文件列表中的文件,因为它们是只读的。创建新的文件列表似乎也是不可能的。使用输入元素的“accepts”属性是否有可能解决您的问题?您可以使用以下命令从文件列表中删除所有文件:$fileToUpload[0]。value=Related post:Hi,只需一件事。文件是一个javascript对象,因此您不能在其上使用。forEach,您应该改为使用[]。forEach.callfiles,functionfile{…}此解决方案仅在您不从表单Submit上载文件而不是将单个文件提交到服务器时有效,我如何才能让它发布整个数组?@AndrewHubbs如何再次使用多个文件输入附加已验证的文件?从输入元素的何处删除文件?如果一个用户上传了5个文件,而你所做的只是操纵一个JavaScript数组,他们仍然会在输入按钮旁边看到“选择了5个文件”。这是个不错的主意。。。我将用newInput替换用于实际表单提交的实际hiddenInput,并将oldInput保持原样。这是一个很好的解决方案,但不幸的是,它在iOS上不起作用
let updateFileList = function (fileField, index) {
let fileBuffer = Array.from(fileField.files);
fileBuffer.splice(index, 1);
/** Code from: https://stackoverflow.com/a/47172409/8145428 */
const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
for (let file of fileBuffer) { dT.items.add(file); }
fileField.files = dT.files;
}