Sending Multipart file and #RequestBody in single request - reactjs

In the React web app I'm developing,there is a file upload part with some user data.However, when I'm trying to upload files, server throws the following error.
org.apache.tomcat.util.http.fileupload.FileUploadException: the
request was rejected because no multipart boundary was found
React side
function fileChangedHandler(event) {
let formData = new FormData();
formData.append("file", event.target.files[0]);
formData.append("name", event.target.files[0].name);
SENDER.post(
"/api/task_resources",{
addedBy: parseInt(localStorage.getItem('id')),
taskId: parseInt(props.taskId)
},{
params: {
file: formData
}
}
)
.then(res => {
if (res.status === 200) {
alert("upload suc");
window.location.reload()
}
})
.catch(err => alert("err"));
}
My Spring Boot controller is as follows.
#PostMapping("/task_resources")
public void addResourceToTask(#RequestParam("file") MultipartFile file,#RequestBody AddTaskResourceRequest addResReq) {
String fileName = fileService.storeFile(file);
String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/api/downloadFile/")
.path(fileName)
.toUriString();
UploadFileResponse response = new UploadFileResponse(fileName, fileDownloadUri,
file.getContentType(), file.getSize());
taskResourceService.addResource(addResReq, fileDownloadUri);
}

You need to send the request using multipart/form-data if your server is especting that. Here is my example implemented using Axios.
const postGalleryImageRequest = async (sessionToken, userLogged, image) => {
const data = new FormData();
data.append('newImage', image);
const result = await api.post('business/' + userLogged.businessId + '/gallery', data, {
headers: {
Authorization: sessionToken,
'Content-Type': 'multipart/form-data',
}
}) .then((response) => {
return response.data
})
.catch(error => {
....
})
return result;
}

Related

react native image picker send to spring boot error

const loadLibrary = useCallback(async () => {
launchImageLibrary(
{
mediaType: 'photo',
},
response => {
if (response?.errorCode) {
console.log('LaunchImageLibrary Error: ', response.errorMessage);
} else {
console.log('response=', response.assets[0]);
const formData = new FormData();
formData.append('image', {
name: response.assets[0].fileName, // require, file name
uri: response.assets[0].uri, // require, file absoluete path
type: response.assets[0].type, // options, if none, will get mimetype from `filepath` extension
});
console.log('formData=', formData);
axios
.post('/users', formData)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
// );
}
},
);
}, [userInfo]);
spring code ---
#PostMapping(value="/api/v1/users")
public String createUser(
#RequestParam("image") MultipartFile image) {
System.out.println(image);
return "";
}
-error--
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
how to deal with?
Previously, this code worked well.
try this and let me know
const formData = new FormData();
formdata.append("image", {type: 'image/jpg', uri:response.assets[0], name:response.assets[0]});
console.log('formData=', formData);
axios
.post('/users', formData)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
// );
}
},
);

send file to server axios

I am trying send file to server with laravel api and react but the response is null this my code in frontend
let File;
const onChangeHandler = (e) => {
File = (e.target.files[0]);
}
const send = () => {
const formData = new FormData();
formData.append("media", File);
console.log(formData)
try {
PostRequest.post("/upload-post", {"media": formData}).then(r => console.log(r.data)).catch((e) => console.log(e));
} catch (error) {
console.log(error)
}
}
and my header :
headers: {
"Content-Type": "multipart/form-data",
"Accept":"application/json",
"Authorization": Token
}
and network tab
img
File log
File log

How to send body with formData inside as a key fetch api

When I try to send image and a path to Api, it sends like [object Object]
export async function uploadImageToCDN(image: FormData, directory: string = 'dir'): Promise<any> {
const token = await authoriseInApi()
const headers = []
headers.push(['Authorization', `Bearer ${token}`])
const data: Content = new Content('multipart-file', {
file: image,
dir: directory
})
return post<any>('https://test-api.test.com/files/upload', data, headers)
}
This is how I collect data and send to Api:
const formData = new FormData()
const imageBase64 = await getBase64(file)
const imageUri = dataURIToBlob(imageBase64)
formData.append('image', imageUri)
const res = uploadImageToCDN(formData)
What is a mistake?
You need to use JSON.stringify(data) to send object parameter:
return post<any>('https://test-api.test.com/files/upload', JSON.stringify(data), headers)
Or if you want to use fectch try same thing:
//POST request with body equal on data in JSON format
fetch('https://example.com/profile', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
I wrote xhr request and everything work fine.
Here is my request:
export async function uploadImageToCDN(formData: FormData): Promise<ICDNUploadResponse> {
return new Promise(async (resolve, reject) => {
const token = await getApiTokenByScope('scope')
const xhr = new XMLHttpRequest()
xhr.open('post', '/api/test/files/upload')
xhr.responseType = 'json'
xhr.setRequestHeader('Authorization', `Bearer ${token}`)
xhr.onload = async () => {
if (xhr.status === 401) {
await refreshApiTokenByScope('scope')
.then(() => {
uploadImageToCDN(formData)
})
}
resolve(xhr.response)
}
xhr.onerror = () => {
reject(xhr.response)
}
xhr.send(formData)
})
}

How to send a file from ReactJs to Flask using Axios

I am attempting to send a file from a ReactJs Frontend, using an axios call, to a flask Backend.
Here is my axios call:
const audio_file = new File(buffer, 'recording.mp3', {
type: blob.type,
lastModified: Date.now()
});
const blobURL = URL.createObjectURL(blob);
this.setState({blobURL, isRecording: false, recorded:true})
let options = {
method: 'POST',
url: flaskEndpoint + "audio/1",
file: audio_file,
crossOrigin:'*'
}
console.log(options)
axios(options)
.then(response => {
console.log(response)
})
.catch(error => {
console.log("Error in the axios call:" + error);
})
At the moment my flask method looks like this :
#app.route('/audio/<int:user_id>', methods=['POST'])
#cross_origin()
def make_audio(user_id):
print(request.files.get('recording.mp3'))
print(request.files)
return 0
Here is the console of the python app:
And here is the web console of the React App:
Am I making a mistake here?
Edit
Ok I tried the suggestion of converting the file to base64 and then sending the file the backend.
This is my new axios call.
let options = {
method: 'POST',
url: flaskEndpoint + "audio/1",
data: convertBlobToBase64(blob),
// file: audio_file,
crossOrigin:'*',
headers: {
'Content-Type': 'application/json'
},
json: true
}
console.log(options)
axios(options)
.then(response => {
console.log(response)
})
.catch(error => {
console.log("Error in the axios call:" + error);
})
});
Here is the convetBlobtoBase64 functions (borrowed from: https://gist.github.com/n1ru4l/dc99062577b746e0783410b1298ab897)
const convertBlobToBase64 = blob => new Promise((resolve, reject) => {
const reader = new FileReader;
reader.onerror = reject;
reader.onload = () => {
resolve(reader.result);
};
reader.readAsDataURL(blob);
});
And here is what is being sent to the backend:
I think this answers my question, although I will create another to work out how to access the data on the flask end.

How to upload image as binary in react native

this is from post man
in react native how can i convert image and upload it to server as binary
this is my code i try to use form data insted of header but still not working
the upload work but the image not showing
ImagePicker.showImagePicker(options, async (response) => {
if (response.didCancel) {
setIsLoading(false);
} else if (response.error) {
setIsLoading(false);
} else if (response.customButton) {
} else {
setIsLoading(true);
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type: mime});
}
var file = dataURLtoFile(
'data:image/png;base64,' + response.data,
'hello2.png',
);
var myHeaders = new Headers();
myHeaders.append('type', '1');
myHeaders.append('uploadPath', 'xxx');
myHeaders.append('Content-Type', 'image/png');
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: file,
processData: false,
contentType: false,
};
fetch(
'xxx',
requestOptions,
)
.then((response) => response.json())
.then((result) => {
after i upload the image this is how it show
I don't know why you convert your file to data:String, and try to upload as image/png content-type. Do you want data:string or as the file itself? if you want to use data:String then your content type should be plain/text.
This is what I normally do to upload image.
const uploadImage = async (response) => {
const put = await fetch(url, { method: 'post', body: response, headers: { "Content-type": response.type } });
}
Where response is the response returned by ImagePicker.showImagePicker
Depending on your server, you may require form data, which then you need to do the formData way.
const uploadImage = async (response) => {
let formData = new FormData();
formData.append('file', response);
//in most case you do not need to create custom header object.
const put = await fetch(url, { method: 'post', body: formData });
}
blob method.
const uploadImage = async (response) => {
var blob = new Blob(response);
//in most case you do not need to create custom header object.
const put = await fetch(url, { method: 'post', body: blob, header: { 'Content-type": response.type });
}
Above example is base on a single file selected, if you select multiple file then response will of course be an array instead.

Resources