我想上傳文件到使用Multer的Node後端。 Multer要求表單以特定方式提交。如果未以這種方式提交,request.file
參數將爲undefined
。我創造了一種通過使用暴力的方法。該工作方式是這樣的:通過FormData上傳文件
指數1.HTML:
<form method="POST" enctype="multipart/form-data" id="fileUploadForm">
<input type="file" id="selectedFile" name="selectedFile" /><br/><br/>
<input type="submit" value="Submit" id="btnSubmit"/>
</form>
...
var btn = document.getElementById('btnSubmit');
btn.addEventListener('click', function(e) {
e.preventDefault();
var form = $('#fileUploadForm')[0];
var data = new FormData(form);
console.log(data);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/upload",
data: data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
success: function (data) {
console.log("SUCCESS!");
},
error: function (e) {
console.log("ERROR : ", e);
}
});
});
上面的代碼文件成功發佈到我的服務器。該服務器有以下幾點:
server.js
app.post('/upload', upload.single('selectedFile'), function(req, res) {
if (req.file) {
console.log('file uploaded');
} else {
console.log('no file');
}
res.send({});
});
使用上面的代碼,「上傳的文件」如預期顯示在控制檯窗口。但是,我需要一個更有活力的方法。出於這個原因,我需要以編程方式在JavaScript中構建表單。在試圖做到這一點,我創建了以下內容:
指數2.HTML [我的UI]
var btn = document.getElementById('btnSubmit');
btn.addEventListener('click', function(e) {
var form = document.createElement('form');
form.action = '/upload';
form.method = 'POST';
form.enctype = 'multipart/form-data';
var node = document.createElement("input");
node.name = 'selectedFile';
node.value = GLOBAL_SELECTED_FILE;
form.appendChild(node);
var data = new FormData(form);
data.append('id', this.id);
console.log(data);
$.ajax({
type: 'POST',
url: '/profile-picture/upload',
enctype: 'multipart/form-data',
data: data,
contentType: false,
processData: false,
success: function(res) {
console.log('success!');
},
error: function(xhr, status, err) {
console.log('error');
}
});
});
這第二種方法是行不通的。爲了澄清,GLOBAL_SELECTED_FILE
變量是從輸入元素中選擇的文件的數據。數據通過FileReader API加載。看起來像這樣:
var GLOBAL_SELECTED_FILE = null;
var fileReader = new FileReader();
fileReader.onload = function(e) {
GLOBAL_SELECTED_FILE = e.target.result;
}
fileReader.readAsDataURL(fileSelected); // file selected comes from the onchange event on a <input type="file">..</input> element
基本上,我正在加載圖像預覽。無論如何,當我點擊工作版本(index-1.html)中的提交按鈕時,我注意到在提琴手中,通過在index-2.html中發送的值發送了不同的值。
隨着指數1.HTML的方法,提琴手顯示在「的TextView」標籤是這樣的:
------WebKitFormBoundary183mBxXxf1HoE4Et
Content-Disposition: form-data; name="selectedFile"; filename="picture.PNG"
Content-Type: image/png
PNG
然而,當我照「的TextView」選項卡中的提琴手發送的數據通過index-2.html,我看到以下內容:
------WebKitFormBoundary9UHBP02of1OI5Zb6
Content-Disposition: form-data; name="selectedFile"
data:image/png;base64,iVBORw0KGg[A LOT MORE TO GO]
這就像FormData對同一個值使用兩種不同的編碼。然而,我不明白爲什麼。如何獲得index-2.html以與index-1.html相同的格式發送圖像,以便Multer將填充req.file屬性?
謝謝!