Bad request status 400 when trying to upload image file to imgur - reactjs

I'm trying upload image file from my React app.
Keep getting 400 error, witch I can't understand why.
That's my TypeScript function's code in React:
public setImage = (args: ChangeEvent<HTMLInputElement>) => {
const image = args.target.files[0];
let formData: FormData = new FormData();
formData.append("profileImage", image, image.name);
const requestOptions = {
method: 'POST',
headers: { 'Authorization': 'Client-ID //my client-id here//' },
image: image
};
fetch('https://api.imgur.com/3/image', requestOptions)
.then(response => response.json())
.then(data => console.log(data));
}
And the error:
{
data: error: "No image data was sent to the upload api"
method: "POST"request: "/3/image"
__proto__: Objectstatus: 400
success: false
__proto__: Object
}
When i'm trying to console my FormData object after appending I can see an empty object.
Thanks for any answer!

The first thing that comes to mind is to log the image object as well and see if there are any problems there.
Also please take a look at this to verify that you're logging your FormData object correctly.
If however, this is still not enough to debug the issue, I would advise you to try rolling a request using something like curl or Fiddler since you are manually creating the POST headers. Because of this, you're not sending the Content-Length header which could cause the imgur api to just skip the whole body of your request.
To get the content lenght you could do something like:
let content-length = JSON.stringify(formData).length;
Then simply:
const requestOptions = {
method: 'POST',
headers: { 'Authorization': 'Client-ID //my client-id here//', 'Content-Length': content-length },
image: image
};
Hope this is useful in some way.

Related

How to send a POST request with variables in React?

I am learning how to send a POST request to an API with React.
What I'm trying to achieve right now is sending a POST request to an API.
The API will insert the event with something like this (what is this method called?):
https://api.com/WebService.asmx/insertEvent?event_id=5&desc=<p>HelloWorld</p>&name=testing
The method that I'm currently using as POST is shown at POST method and it returns me with the error unexpected token '<' in json at position 0 and the result that I get when I console.log(JSON.stringify(event)) is something like this:
{"event_id":"5","desc":"<p>HelloWorld</p>","name":"testing"}```
POST method
const response = await fetch('https://api.com/WebService.asmx/insertEvent',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(event)
})
Edit: I've fixed the above error by encoding the HTML that I need to send. This is now my latest POST method, but I'm still facing error 500 for some reason even though it works when I copy and pasted the URL+params from the console.log that has the error shown:
const addBulletin = async (event) => {
console.log(event, '--event')
const url = 'https://api.com/WebService.asmx/insertEvent';
axios.post(url, null, { params: {
title: event.title,
desc: event.desc,
image: event.image,
employee: event.employee,
entity: event.entity,
startDate: event.startDate,
endDate: event.endDate,
createdBy: event.createdBy
}})
.then(response => console.log(response.status))
.catch(err => console.warn(err));
};
Edit: I've tested the API on a vanilla JS project using .ajax with POST, and it works, so I think the API shouldn't be a problem.
var json = $('.insert-form').serialize();
$.ajax({
type: "POST",
url: "https://api.com/WebService.asmx/insertEvent",
data: json,
async: true,
success: function (response) {
alert("Event has been successfully created!");
},
error: function (response) {
console.log(response);
}
});
The API you are sending the request to expects a query parameter (data in the URL).
https://api.com/WebService.asmx/insertEvent?event_id=5&desc=<p>HelloWorld</p>&name=testing
In this request, we are sending 3 query params: event_id, desc, and name.
To send this kind of request from React, you should not use request body. Instead. I advise you to use axios to make it easier. It's a very powerful library, better than using fetch. It should be done this way:
axios.post(`https://api.com/WebService.asmx/insertEvent`, null, { params: {
event_id: eventId,
desc
}})
.then(response => response.status)
.catch(err => console.warn(err));
This may help: How to post query parameters with Axios?

Fetch 401 Authorization issue

I've started to build a project using WooComeerce and React.js, but I have one question.
When I try to get the data, for example: "products", received an issue 401 unauthorized..
I've tested my request into Postman/Insomnia and everything is working as expected. I think the problem is coming from the headers part, but for now I can't handle the issue..
Also my response headers are empty!
Here is my code:
const getProducts = async () => {
const response = await fetch(`${process.env.REACT_APP_API_URL}products?consumer_key=${process.env.REACT_APP_API_CONSUMER_KEY}&${process.env.REACT_APP_CONSUMER_SECRED_KEY}`,
{
method: "GET",
mode: "cors",
credentials: "include",
headers: {
"Authorization": `Basic ${process.env.REACT_APP_API_CONSUMER_KEY}`,
"Content-Type": "application/json",
},
}
);
return response;
};
How can i fix that issue?
Note: I'm not using WooCommerce REST API package.
Thank you in advance!
Usually the basic auth string is base64-encoded string username:password. However i see the consumer key being used in the req and the header. Can you please double check your authorization header?

File Upload using spring rest and axios, no multipart boundary was found

I have some issues in file uploading using spring rest and react and axios,
my back-end code is
#PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity uploadFile(#RequestParam MultipartFile file) {
return ResponseEntity.ok().build();
}
and I can upload file using postman, but by using axios I got some errors.
nested exception is org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
here is my code:
let formData = new FormData();
formData.append("file", this.state.selectedFile);
axios({
method: "post",
url: url,
data: {
formData
}
})
also if I put
headers: { "Content-Type": "multipart/form-data" }
I got error too,
can anyone tell me what are my mistakes please?
It may be beacause you are creating a new object and sending the data inside the object
Try this data: formData
let formData = new FormData();
formData.append("file", this.state.selectedFile);
axios({
method: "post",
url: url,
data: { formData},
{...axios.default.headers,
...{headers: { "Content-Type": "multipart/form-data" }}
}
})
You dont need to put any headers as it will automatically , decides the parameters of headers , when you do it manually you need to explicitly decides few parameters which is quite difficult to judge , so dont give headers

Axios in React app. Posting image with form data sends request with empty body

I'm trying to send image file to my backend API. Last works fine with Postman. The problem is not with image, I'm not able to send any request with axios and form data, no meter I append image or not.
Everything works fine with fetch. It took time to understand, that fetch does not need any content type, and last generates automatically as multipart/form-data with right boundary.
As written axios should do same as fetch, but it does not generate or change its content-type. Passing header 'content-type' : 'multipart/form-data does not do the trick of course. When I do not set content type it just use application/json. I was not able to find anything like that in documentation. Everywhere its says, that axios should create content type header automatically.
My axios version is 0.18.0.
Here is code, it can't be more simple =)
axios
.post(url, payload)
#######UPDATE#######
It turned out the problem was with axios interceptor. If you don't use interceptors you won't get this problem. So when I created new instance and deleted all headers no interceptors where called that's why my code worked. But let me bring more details to help others avoid this pain. Interceptor has transformRequest function where this part of code exists
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
where setContentTypeIfUnset function is
function setContentTypeIfUnset(headers, value) {
if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
headers['Content-Type'] = value;
}
}
So if your object has undefined headers you will also pass this situation. But in my case even after deleting all headers I must pass some header to my application. And on setting it interceptor calls that transfromRequest function which adds that header to my formdata request.
I hope in future releases axios will fix this issue.
#######OLD ANSWER#######
As I guessed, somehow axios in my project set its default value for header content type and even setting it as 'content-type' : undefined did not overwrite that value.
Here is solution
let axiosInstance = axios.create();
delete axiosInstance.defaults.headers;
Then use that instance.
Spent whole day to find this solution.
const formData = new FormData();
formData.append('image', image); // your image file
formData.append('description','this is optional description');
Axios.post(`your url`, {body:formData}, {
headers: {
'content-type': 'multipart/form-data'
}
})
Can you please try this code once ?
You can try like this:
axios({
method: 'post',
url: 'myurl',
data: bodyFormData,
headers: {'Content-Type': 'multipart/form-data' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});

Invalid input file upload api platform

I'm trying to upload a file using api platform file upload. I'm using React-redux with redux-saga to make this request, but the server keeps throwing bad request response.
Api platform documentation says the following for making the request:
This endpoint accepts standard multipart/form-data-encoded data, but
not JSON data. You will need to format your request accordingly.
My Saga:
I tried appending my uploaded file to formData and use that as body for my request.
let data = new FormData();
data.append("file", action.payload.file)
const fileResponse = yield call(
fetch,
`${api.url}/api/media_objects`,
{
method: 'POST',
mode: 'no-cors',
body: data,
headers: { 'content-type': 'multipart/form-data' }
}
);
return console.log(fileResponse);
This is the api platform example request for posting a new media object
curl -X POST
"https://api.myroute/api/media_objects" -H
"accept: application/ld+json" -H "Content-Type: multipart/form-data"
-F "file=#1.6b.jpg;type=image/jpeg"
Api platform keeps returning a 400 error, which refers to invalid input. Any idea how the valid input should look like?
For my media object entity I followed the api platform documentation, so it looks exactly the same as in the docs
Details matter
headers: { 'content-type': 'multipart/form-data' }
It should be
headers: { 'Content-Type': 'multipart/form-data' }
There is no 'content-type', only 'Content-Type' header is defined (RFC) and widely accpeted.
I had a very similar issue recently (I can't remember the exact error), with API Platform (and the MediaObject entity), and React - redux (but no redux-saga).
I was able to fix it by removing the header part of my request :
headers: { 'content-type': 'multipart/form-data' }
So my new request looked exactly like that in my case :
const formData = new FormData();
formData.append('file', file);
return fetch(id, {
method: 'POST',
body: formData
})
...
I don't really know why, but it did the trick. Maybe it is handled automatically since we send a FormData object.
Hope it can work for you too !

Resources