Я знаю, что об этом уже спрашивали, но ни одно из решений не работает для меня. Сначала я пытался решить эту проблему с помощью axios, но, читая об этом, кажется, есть ошибка, которая не позволяет мне использовать его для загрузки файлов. Так что я застрял с fetch.
Это моя функция загрузки:
export async function postStudyPlan(plan, headers) {
const options = {
method: "POST",
body: plan
}
return fetch(`${HOST}:${PORT}/study-plans/add`, options)
.then(res => {return res.json()})
.catch(err => console.info(err));
}
Вот как я это называю:
onStudyPlanUpload(files) {
const file = files[0];
let formData = new FormData();
formData.append("pdf", file);
formData.append("comments", "A really lit study plan!");
formData.append("approved", true);
formData.append("uploaded_by", "Name");
formData.append("date_uploaded", "2012-02-1");
formData.append("university", "australian_national_university");
let plan = {
"pdf": file,
"comments": "A really lit study plan!",
"approved": true,
"uploaded_by": "Name",
"date_uploaded": Date.now(),
"university": "australian_national_university"
}
postStudyPlan(formData)
.then(res => console.info(res))
.catch(err => console.info(err))
}
Я знаю, что file на самом деле файл. Всякий раз, когда я меняю "pdf" на обычную строку, все работает нормально. Но когда я использую объект File, я ничего не получаю на свой сервер, только пустой объект. Что мне здесь не хватает? Я чувствую, что мое решение в основном идентично любому другому решению, которое я нашел в Интернете.
Редактировать:
Также пробовал использовать FormData и добавлять headers: {"Content-Type": "application/x-www-form-urlencoded"} к опциям. Тот же результат.
Редактировать 2 Я начинаю думать, что проблема может быть в моем бэкэнде! Это мой бэкэнд, и я действительно получаю некоторые результаты для события «данные». Не знаю как обработать...
router.route("/add").post((req, res) => {
req.on("data", function(data) {
console.info("got data: " + data.length);
console.info("the Data: ?" )
// let t = new Test(data);
// t.save()
// .then(res => console.info(res))
})
req.on("end", function(d) {
console.info("ending!");
})
req.on("error", function(e){
console.info("ERROR: " + e);
})
});



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы должны использовать FormData с 'Content-Type': 'application/x-www-form-urlencoded' в качестве заголовка выборки.
Я хочу, чтобы вы попробовали простой подход. Вместо добавления файла в FormData создайте экземпляр фактической формы.
onStudyPlanUpload = (event) => {
event.preventDefault();
const formData = new FormData(event.target);
postStudyPlan(formData)
.then(res => console.info(res))
.catch(err => console.info(err))
}
HTML
<form onSubmit = {this.onStudyPlanUpload} encType = "multipart/form-data" ref = {el => this.form = el}>
<input type = "file" name = "pdf" onChange = {() => { this.form.dispatch(new Event('submit'))}/>
<input type = "hidden" name = "comments" value = "A really lit study plan!" />
<input type = "hidden" name = "approved" value=true />
<input type = "hidden" name = "uploaded_by" value = "Name"/>
<input type = "hidden" name = "date_uploaded" value = "2012-02-1"/>
<input type = "hidden" name = "university" value = "australian_national_university"/>
</form>
При изменении ввода файла он вызовет отправку формы (onStudyPlanUpload).
Надеюсь, это сработает!
Я отвечу на свой вопрос. Если кто-то еще столкнется с этой проблемой, это Бэкэнд, который неисправен. Это мое окончательное решение, использующее busboy для обработки входящих данных формы. Я ничего не менял на своем сервере, но мой роутер нужно было обновить. Вот мой маршрутизатор, отвечающий за POST-запросы:
const express = require("express");
const mongoose = require("mongoose");
require('./../../models/Test');
const path = require("path");
const fs = require("fs");
const router = express.Router();
const Busboy = require("busboy");
router.route("/add").post((req, res, next) => {
let busboy = new Busboy({headers: req.headers});
// A field was recieved
busboy.on('field', function (fieldname, val, valTruncated, keyTruncated) {
if (req.body.hasOwnProperty(fieldname)) { // Handle arrays
if (Array.isArray(req.body[fieldname])) {
req.body[fieldname].push(val);
} else {
req.body[fieldname] = [req.body[fieldname], val];
}
} else { // Else, add field and value to body
req.body[fieldname] = val;
console.info(req.body);
}
});
// A file was recieved
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
console.info("File incoming: " + filename);
var saveTo = path.join('.', filename);
console.info('Uploading: ' + saveTo);
file.pipe(fs.createWriteStream(saveTo));
});
// We're done here boys!
busboy.on('finish', function () {
console.info('Upload complete');
res.end("That's all folks!");
});
return req.pipe(busboy);
});
module.exports = router;
Наконец-то моя законченная функция onStydyPlanUpload()!
onStudyPlanUpload(files) {
const file = files[0];
let formData = new FormData();
formData.append("pdf", file, file.name);
formData.append("comments", "A really lit study plan!");
formData.append("approved", true);
formData.append("uploaded_by", "Melker's mamma");
formData.append("date_uploaded", new Date());
formData.append("university", "australian_national_university");
const HOST = "http://localhost";
const PORT = 4000;
axios.post(`${HOST}:${PORT}/test/add`, formData)
.then(res => console.info(res))
.catch(err => console.info(err))
}
Получил помощь от: https://gist.github.com/shobhitg/5b367f01b6daf46a0287