How to send canvas image to server react/redux - javascript

How send canvas to server?
I'm using react-cropper
Output is base64 but i need send it like form data with fetch
Is it possible to do like that?
static upload(files) {
let data = new FormData();
data.append(files[0].name, files[0]);
const request = new Request("/api/upload-photo", {
method: 'POST',
credentials: 'same-origin',
body: JSON.stringify(files)
});
return fetch(request).then(response => {
return response.json();
}).catch(error => {
return error;
});
}

Related

Getting empty data field at backend when parsing formData using fetch

I am trying to send input fields' data to back end using fetch. I used formData.append to combine the data. when the fetch runs on backend I am getting empty list.
async function autosave()
{
let formdata =new FormData();
let blogImage = document.querySelector("#blog_image").files[0];
let imageName = document.querySelector("#blog_image").files[0].name;
let blogTitle = blog_title.value.trim();
let contentType = document.querySelector("#content_type").checked;
let blogId = document.querySelector("#id_val").value;
let blogContent = editorbody.innerHTML;
// console.log(document.querySelector("#blog_image").files[0])
formdata.append("blog_image", blogImage, imageName)
formdata.append("blog_title", blogTitle);
formdata.append("content_type", contentType)
formdata.append("blog_id", blogId);
formdata.append("content",blogContent)
await fetch("/blog/autosave/",{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'mode':'no-cors'
},
method: "POST",
body:JSON.stringify(formdata)
}).then((res) => {return res.json()})
.then((data) => {
if (data.status == 200){
// function savesuccessFun();
console.log("Blog saved successfully");
}
else{
// savefailFun();
console.log("Opps blog can not be saved");
}
}).catch(err => console.log(err));
I know only front end. at back end we are getting data using data = json.loads(request.body)
NOTE: I mage should not be send in base64 format.
All variables are taking data from form fields.

passing binary data to rest-api

I want to upload a thumbnail to viemo api , and based on Vimeo doc, I must include the thumbnail file as binary data in the request body, I have to upload the thumbnail from the client side "fontend" and will send the request from the rest-api "backend" the problem is my rest-api can't receive the binary data, properly because I'm using express.js, is there any way to handle the binary data in the backend.
the steps as following:
client side sent thumbnail data => backend receive the data through the request body and send it to => endpoint
client side request
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('selectedFile', new Blob([selectedFile], { type: 'application/json' }));
formData.append('uploadLink', uploadLink);
const headers = {
'Content-Type': 'application/json',
Accept: 'application/vnd.vimeo.*+json;version=3.4',
};
try {
axios
.post(`${backendPostPath}/thumbnail-upload`, formData, {
headers,
})
.then((response) => {
applyThumbnial();
console.log(`${uploadLink}link for upload`);
});
} catch (error) {
console.log(error);
}
};
backend request can't receive the body request of frontend post as binary data,
const ThumbnailUpload = async (req, res) => {
const { uploadLink } = req.body;
const { selectedFile } = req.body;
console.log(uploadLink);
const clientServerOptions = {
uri: `${uploadLink}`,
encoding: null,
body: JSON.stringify({
name: uploadLink,
file: selectedFile,
}),
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Accept: 'application/vnd.vimeo.*+json;version=3.4',
Authorization: getVimeoAuthorization(),
},
};
request(clientServerOptions, function (error, response) {
if (error) {
res.send(error);
} else {
const body = JSON.parse(response.body);
res.send(body);
}
});
};
is there any way to make the backend request body fetch the binary data, as I getting the data as "undefined"
Sorry for late update, I solved this issue by using the same put request form the client side, as the put request don't require Vimeo access token, so you can use the same put request i mentioned above, and remove authentication from the header, like following
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('selectedFile', new Blob([selectedFile], { type: 'image/jpg, image/png' }));
// formData.append('uploadLink', uploadLink);
const headers = {
'Content-Type': 'image/jpg, image/png',
Accept: 'application/vnd.vimeo.*+json;version=3.4',
};
try {
axios
.put(`${uploadLink}`, formData, {
headers,
})
.then((response) => {
console.log(`${uploadLink}link for upload`);
});
} catch (error) {
console.log(error);
}
};

Why am I getting a 500 when uploading file via the browser but not via Postman? [duplicate]

Using raw HTML when I post a file to a flask server using the following I can access files from the flask request global:
<form id="uploadForm" action='upload_file' role="form" method="post" enctype=multipart/form-data>
<input type="file" id="file" name="file">
<input type=submit value=Upload>
</form>
In flask:
def post(self):
if 'file' in request.files:
....
When I try to do the same with Axios the flask request global is empty:
<form id="uploadForm" enctype="multipart/form-data" v-on:change="uploadFile">
<input type="file" id="file" name="file">
</form>
uploadFile: function (event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
If I use the same uploadFile function above but remove the headers json from the axios.post method I get in the form key of my flask request object a csv list of string values (file is a .csv).
How can I get a file object sent via axios?
Add the file to a formData object, and set the Content-Type header to multipart/form-data.
var formData = new FormData();
var imagefile = document.querySelector('#file');
formData.append("image", imagefile.files[0]);
axios.post('upload_file', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
Sample application using Vue. Requires a backend server running on localhost to process the request:
var app = new Vue({
el: "#app",
data: {
file: ''
},
methods: {
submitFile() {
let formData = new FormData();
formData.append('file', this.file);
console.log('>> formData >> ', formData);
// You should have a server side REST API
axios.post('http://localhost:8080/restapi/fileupload',
formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}
).then(function () {
console.log('SUCCESS!!');
})
.catch(function () {
console.log('FAILURE!!');
});
},
handleFileUpload() {
this.file = this.$refs.file.files[0];
console.log('>>>> 1st element in files array >>>> ', this.file);
}
}
});
https://codepen.io/pmarimuthu/pen/MqqaOE
If you don't want to use a FormData object (e.g. your API takes specific content-type signatures and multipart/formdata isn't one of them) then you can do this instead:
uploadFile: function (event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': file.type
}
})
}
Sharing my experience with React & HTML input
Define input field
<input type="file" onChange={onChange} accept ="image/*"/>
Define onChange listener
const onChange = (e) => {
let url = "https://<server-url>/api/upload";
let file = e.target.files[0];
uploadFile(url, file);
};
const uploadFile = (url, file) => {
let formData = new FormData();
formData.append("file", file);
axios.post(url, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
}).then((response) => {
fnSuccess(response);
}).catch((error) => {
fnFail(error);
});
};
const fnSuccess = (response) => {
//Add success handling
};
const fnFail = (error) => {
//Add failed handling
};
This works for me, I hope helps to someone.
var frm = $('#frm');
let formData = new FormData(frm[0]);
axios.post('your-url', formData)
.then(res => {
console.log({res});
}).catch(err => {
console.error({err});
});
this is my way:
var formData = new FormData(formElement);
// formData.append("image", imgFile.files[0]);
const res = await axios.post(
"link-handle",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
},
}
);
How to post file using an object in memory (like a JSON object):
import axios from 'axios';
import * as FormData from 'form-data'
async function sendData(jsonData){
// const payload = JSON.stringify({ hello: 'world'});
const payload = JSON.stringify(jsonData);
const bufferObject = Buffer.from(payload, 'utf-8');
const file = new FormData();
file.append('upload_file', bufferObject, "b.json");
const response = await axios.post(
lovelyURL,
file,
headers: file.getHeaders()
).toPromise();
console.log(response?.data);
}
There is an issue with Axios version 0.25.0 > to 0.27.2 where FormData object in a PUT request is not handled correctly if you have appended more than one field but is fine with one field containing a file, POST works fine.
Also Axios 0.25.0+ automatically sets the correct headers so there is no need to specify Content-Type.
For me the error was the actual parameter name in my controller... Took me a while to figure out, perhaps it will help someone. Im using Next.js / .Net 6
Client:
export const test = async (event: any) => {
const token = useAuthStore.getState().token;
console.log(event + 'the event')
if (token) {
const formData = new FormData();
formData.append("img", event);
const res = await axios.post(baseUrl + '/products/uploadproductimage', formData, {
headers: {
'Authorization': `bearer ${token}`
}
})
return res
}
return null
}
Server:
[HttpPost("uploadproductimage")]
public async Task<ActionResult> UploadProductImage([FromForm] IFormFile image)
{
return Ok();
}
Error here because server is expecting param "image" and not "img:
formData.append("img", event);
public async Task<ActionResult> UploadProductImage([FromForm] IFormFile image)

How to convert reponse stream to blob on javascript client side?

I am unable to create a blob from the response stream of a request (the response comes from a node js server), here is the code:
fetch('/api/load', {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
body: src
}).then((response) => {
const reader = response.body.getReader()
return new ReadableStream({
start(controller) {
return pump()
function pump() {
return reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
controller.enqueue(value);
return pump();
})
}
}
})
}).then((stream) => {
// What to do next with the stream???
})
I already tried new Blob([new Uint8Array(stream)], {type: 'image/jpeg'}), but it doesn't work :(
What is the correct way to create a blob from the stream?

Is it possible to send data and files in the same request?

I have an API that receives uploads of APP files and images
To send from APP to the API I use fetch
const data = new FormData();
let i = 0;
export const dataPush = (fileUri, fileType, fileName) => {
data.append('file'+i, {
uri: fileUri,
type: fileType,
name: fileName
});
i++;
};
export const uploadFiles = () => {
console.log(data);
fetch('http://192.168.0.23/apiapp/public/api/annex', {
method: 'post',
body: data
}).then(res => {
console.log(res)
});
}
But I'd like to send in the same request data obtained from a form
But I did not find a way to do it, always or just send the data, or just send the files
Is it possible to send everything in the same request? And if possible, how?
You just append whatever data that you desire that isn't file data to the FormData object.
data.append("not_a_file", "This is a string");
I did so based on Quentin's response and it worked
const formData = new FormData();
const i = 0;
export const filePush = (fileUri, fileType, fileName) => {
formData.append('file'+i, {
uri: fileUri,
type: fileType,
name: fileName
});
i++;
};
export const dataPush = (name, content) => {
formData.append(name, content);
};
export const uploadFiles = () => {
fetch('http://192.168.0.23/apiapp/public/api/annex', {
method: 'post',
body: formData
}).then(res => {
console.log(res._bodyText)
}).catch(error => {
console.log(error.message)
});
}

Categories

Resources