我有表格。
<form id="add_content" enctype="multipart/form-data" action="/contents/create" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="*****" autocomplete="off" />
<input type="hidden" value="*****" id="database_id" name="database_id">
<div id="drop-area">
<input type="file" id="file_list" name="file_list" multiple>
</div>
</form>
我有一些 JavaScript 来添加放置事件并处理所有事件。
let dropArea = document.getElementById('drop-area')
dropArea.addEventListener('drop', handleDrop, false)
function handleDrop(e) {
let dt = e.dataTransfer
let files = dt.files
handleFiles(files)
}
function handleFiles(files) {
let form = document.getElementById('add_content')
console.log(files)
let file_list = document.getElementById('file_list')
console.log(file_list.files.length)
form.submit();
}
我将一些(两个)文件拖放到控制台中,我可以看到 FileList。
FileList {0: File, 1: File, length: 2}
0: File {name: 'kk.wav', lastModified: 1671550812159, lastModifiedDate: Tue Dec 20 2022 16:40:12 GMT+0100 (Central European Standard Time), webkitRelativePath: '', size: 832216, …}
1: File {name: 'kk.marcos.wav', lastModified: 1671550812023, lastModifiedDate: Tue Dec 20 2022 16:40:12 GMT+0100 (Central European Standard Time), webkitRelativePath: '', size: 1147470, …}
length: 2
[[Prototype]]: FileList
但是 console.log(file_list.files.length) 在控制台上写入 '0'
提交表单后,Payload 如下所示。
authenticity_token: *****
database_id: *****
file_list: (binary)
但是在我的控制器中 file_list 是 nil
def create
database_id = params[:database_id]
file_list = params[:file_list]
puts "================================================================="
puts file_list.class
puts "================================================================="
App 1686102 output: =================================================================
App 1686102 output: NilClass
App 1686102 output: =================================================================
然后,我向我的 javascript 函数 handleFiles 添加一些代码,以将 FileList 添加到我的输入类型文件
function handleFiles(files) {
let form = document.getElementById('add_content')
console.log(files)
let file_list = document.getElementById('file_list')
// Add FileList to the input type file
file_list.files = files
console.log(file_list.files.length)
form.submit();
}
现在 console.log(file_list.files.length) 写入 '2' (这很好),现在控制器收到一个文件,但只有一个文件(最后一个)。不是两个。
App 1686102 output: =================================================================
App 1686102 output: ActionDispatch::Http::UploadedFile
App 1686102 output: =================================================================
如果我尝试在控制器中获取files_list.length,我会得到
undefined method `length' for #<ActionDispatch::Http::UploadedFile:0x00007f356c0dd1c8 @tempfile=#<Tempfile: (closed)>, @content_type="audio/wav", @original_filename="kk.marcos.wav", @headers="Content-Disposition: form-data; name=\"file_list\"; filename=\"kk.marcos.wav\"\r\nContent-Type: audio/wav\r\n">
发送或接收多个文件的正确方式是什么?
嗯,就像更改输入文件的名称一样简单。
<input type="file" id="file_list[]" name="file_list[]" multiple>
而不是
<input type="file" id="file_list" name="file_list" multiple>
也许我的重复了。