I have object like this:
{
"name": "filename",
"size": 3523507,
"type": "image/png",
"extension": "png",
"url": "blob:http://localhost:8081/082e9c22-9869-4289-a9c8-e36b0640e61c"
}
And i need upload it to backend. I try it:
const session = axios.create({
baseURL: debug ? 'http://localhost:8000': '',
xsrfCookieName: CSRF_COOKIE_NAME,
xsrfHeaderName: CSRF_HEADER_NAME,
});
let formData = new FormData();
formData.append('file', file, 'file.name');
return session.post(`/chats/files/`,{...formData},), {
headers: {
"Content-Type": `multipart/form-data`,
}
}
But it doesn't work to add Blob to the formData
UPD I get an object with files from the send-message method in the vue-advanced-chat ponent in this form:
{
"name": "filename",
"size": 3523507,
"type": "image/png",
"extension": "png",
"localUrl": "blob:http://localhost:8081/aae047a9-5f9e-481f-b0cc-17febe954c31",
"blob": {}
}
Then I format it to display in the interface before uploading to the server
UPD2
I converted blob to file
send_file(roomId, messageId, blob_file, isAudio, duration) {
let formData = new FormData();
let file = new File([blob_file.blob], blob_file.name);
formData.append('file[]', file, blob_file.name);
return session.post(`/chats/files/`,
{'chat': roomId, 'message': messageId, ...formData},), {
headers: {
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,
},
timeout: 30000,
}
},
and still get: {"file":["No files were sent."]}
I have object like this:
{
"name": "filename",
"size": 3523507,
"type": "image/png",
"extension": "png",
"url": "blob:http://localhost:8081/082e9c22-9869-4289-a9c8-e36b0640e61c"
}
And i need upload it to backend. I try it:
const session = axios.create({
baseURL: debug ? 'http://localhost:8000': '',
xsrfCookieName: CSRF_COOKIE_NAME,
xsrfHeaderName: CSRF_HEADER_NAME,
});
let formData = new FormData();
formData.append('file', file, 'file.name');
return session.post(`/chats/files/`,{...formData},), {
headers: {
"Content-Type": `multipart/form-data`,
}
}
But it doesn't work to add Blob to the formData
UPD I get an object with files from the send-message method in the vue-advanced-chat ponent in this form:
{
"name": "filename",
"size": 3523507,
"type": "image/png",
"extension": "png",
"localUrl": "blob:http://localhost:8081/aae047a9-5f9e-481f-b0cc-17febe954c31",
"blob": {}
}
Then I format it to display in the interface before uploading to the server
UPD2
I converted blob to file
send_file(roomId, messageId, blob_file, isAudio, duration) {
let formData = new FormData();
let file = new File([blob_file.blob], blob_file.name);
formData.append('file[]', file, blob_file.name);
return session.post(`/chats/files/`,
{'chat': roomId, 'message': messageId, ...formData},), {
headers: {
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,
},
timeout: 30000,
}
},
and still get: {"file":["No files were sent."]}
Share Improve this question edited Jul 8, 2022 at 14:02 Алексей Стародубцев asked Jul 5, 2022 at 13:36 Алексей СтародубцевАлексей Стародубцев 5372 gold badges5 silver badges18 bronze badges 4- According to this answer, the blob URL is internal data. can you explain where the object above is ing from? – Yedidya Rashi Commented Jul 7, 2022 at 17:52
- Thanks for the information, I updated the question, I also have Blob objects, but still I don’t understand how to add them to formData correctly – Алексей Стародубцев Commented Jul 8, 2022 at 10:01
-
i think that you are missing this:
formData.append('file[]', file, 'file.name');
file like that want array to be passed correctly – Levi D. Commented Jul 8, 2022 at 13:29 - Did not help, I try to send a file in base64, blob, file - I get an error – Алексей Стародубцев Commented Jul 8, 2022 at 15:11
3 Answers
Reset to default 11After several days of searching, debugging and dozens of attempts, I managed to find a solution.
- You need a Blob object, not a URL
- You need to convert Blob to File
let file = new File([blob_file.blob], fileName);
- To correctly identify the file type, you need to add blob_file.extension to the name
let fileName = `${blob_file.name}.${blob_file.extension}`;
- You need to add all attributes to formData
formData.append('file', file, fileName);
formData.append('chat', roomId);
formData.append('message', messageId);
- Specify 'Content-Type':
multipart/form-data
, and don't specify _boundary - because in new versions of formData it is determined automatically!
headers: {
'Content-Type': `multipart/form-data`,
},
so the final version of the code looks like this:
send_file(roomId, messageId, blob_file) {
let formData = new FormData();
let fileName = `${blob_file.name}.${blob_file.extension}`;
let file = new File([blob_file.blob], fileName);
formData.append('file', file, fileName);
formData.append('chat', roomId);
formData.append('message', messageId);
return session.post(`/chats/files/`,
formData, {
headers: {
'Content-Type': `multipart/form-data`,
},
})
You are not sending data in correct way. It should be:
export const uploadFileRequest = ({ file }) => {
const data = new FormData();
data.append('file', file, file.name);
return session.post(`/chats/files/`, data, {
headers: {
'Content-Type': `multipart/form-data;boundary=${data._boundary}`,
},
timeout: 30000,
});
};
it should work, for reference https://medium./@fakiolinho/handle-blobs-requests-with-axios-the-right-way-bb905bdb1c04
I came to this question and after a few hours, here are my findings and solutions. First, I realized binary data like blobs cannot be send through json. Axios normally sends its data as json and hence, nothing would be received on the backend. Here setting the header was required:
const data = new FormData();
data.append("username", "Chris");
data.append("file", userAnswers[0].value);
let apiEndPoint = "/api/plans/answer/speaking/" + planId;
axiosInstance
.post(apiEndPoint, data, {
headers: {
"Content-Type": `multipart/form-data; boundary=${data._boundary}`,
},
timeout: 30000,
})
.then(() => {
toast({
title: `Submitted`,
status: "success",
isClosable: true,
});
navigate("/");
})
We see the use of FormData as well. It is necessary. Maybe you created a form and mentioned the type there. I wasn't using a form.
<form action="/stats" enctype="multipart/form-data" method="post">
The second important part was handling the backend. The frontend part is not enough. Multer middleware is required.
const multer = require("multer");
const upload = multer({ dest: "./public/data/uploads/" });
router.post(
"/answer/speaking/:id",
[auth, validateObjectId, upload.single("file")],
async (req, res) => {
winston.info(req.file);
winston.info(req.body);
res.send();
return;
})