can't send multipart with fetch but axios works fine - javascript

Here is my code:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
body: payload,
});
}
function uploadImage2(payload) {
return axios.post('/api/storage/upload/image/', payload, {
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
});
}
function test(file, meta_data) {
var formBody = new FormData();
formBody.set('image', file);
formBody.set('meta_data', meta_data);
uploadImage(formBody);
// doesn't work
uploadImage2(formBody);
// works
}
Can someone please explain to me how I'm supposed to send multipart requests with fetch?
The error I get with this code is: 400 bad request, file and meta_data are null.

Do not use this header: 'Content-Type': 'multipart/form-data'.
Remove the header and it should work.
Explanation:
When using fetch with the 'Content-Type': 'multipart/form-data' you also have to set the boundary (the separator between the fields that are being sent in the request).
Without the boundary, the server receiving the request won't know where a field starts and where it ends.
You could set the boundary yourself, but it's better to let the browser do that automatically by removing the 'Content-Type' header altogether.
Here's some more insight: Uploading files using 'fetch' and 'FormData'

Here is what worked for me:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
},
body: payload,
});
}
By comparing the cURL requests sent by the browser I discovered that in the axios request has this:
"Content-Type": "multipart/form-data; boundary=---------------------------19679527153991285751414616421",
So I figured that when you manually specify the content type, fetch respects that and doesn't touch anything while still does it's thing the way it wants:-/ so you just shouldn't specify it, fetch will know itself since you are using formData()

Related

Does puppeteer support PUT method

Like the title.
Im trying to automatically crawling data and then edit them using puppeteer, heres my code
page2.on('request', interceptedRequest => {
var data = {
'method': 'PUT',
'putData': JSON.stringify(stage),
'headers': {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
};
interceptedRequest.continue(data);
});
So i encounter an error as the response from the server
{"timestamp":"2021-01-23T14:19:01.276+00:00","status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported"}
Any ideas guys? Thanks for reading
Edit: i have also tried postData in the intercept

javascript fetch is not posting to rest api endpoint while postman is doing

I have a rest api endpoint and I am checking it using POSTMAN which is posting correctly. But, when I am doing it using JAVASCRIPT FETCH, I am not able to post it. Below is my code for fetch:
const { inputAOI, wktForCreation } = this.state
fetch('http://192.168.1.127:8080/aoi/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ userName: 'fuseim', aoiName: inputAOI, wkt: wktForCreation }),
mode: 'no-cors'
}).then(function (response) {
if (response.ok) {
return response.json()
} else {
throw new Error('Could not reach the API: ' + response.statusText)
}
}).then(function (data) {
console.log({ data })
}).catch(function (error) {
console.log({ error })
})
Below is the image for the request headers.
It is seen in the above image that in Request Headers, the Content-Type is still text/plain but I am sending application/json as shown in above fetch code.
Check the response preview in console.
Below is correct POSTMAN request:
As hinted in the comments, the problem is with the mode:"no-cors"
Content-Type is considered a simple header, and should be allowed without cors, but only with the following values:
application/x-www-form-urlencoded
multipart/form-data
text/plain
See: https://fetch.spec.whatwg.org/#simple-header
If you are running the API on the same host/port as the script, you should use mode: "same-origin" alternatively add the host/port that the script is running on as an allowed origin on the API.
For more information about CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Instead of
headers: {
'Content-Type': 'application/json'
}
you could try:
headers: new Headers({
'Content-Type': 'application/json'
})

Requested property name of a value that is not an object - while fetching data from server

I am new to the react-native world. I am using the following code to get a response from server. While debugging it is working fine, but without debugging it gives below error
fetch("http://hcdsny.trantorinc.com/index.php/api/register", {
method: "POST",
headers: 'application/x-www-form-urlencoded',
body: JSON.stringify(data)
})
.then(function(response){
return response.json();
})
.then(function(data){
}).catch((error) => {
console.error(error);
});
Thanks in Advance!
I have faced the same issue and solved it by replacing headers with an object instead of a string.
Try this.
Replace (Header as a String)
headers: 'application/x-www-form-urlencoded'
with (Header as a Object)
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
It may work for you.
Headers should be an object, not a string. The key for the header you are looking for is content-type:
headers: {
'content-type': 'application/x-www-form-urlencoded'
}

Do I have a complete HTTP header to authenticate properly

Building a Django Rest Framework. when I user 'curl' to call the API with a valid token it works:
curl -viL -H "Authorization: Token 65c38dfe0c910b727197683aebdcc1c67c1b7aa3" http://127.0.0.1:8000/api/habit/
The same API call via my javascript call, fails and Django see it as an anonymous user and errors out.
fetchHabits: function() {
console.log('Token '+this.authToken.token);
fetch('http://127.0.0.1:8000/api/habit/?format=json',{
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token '+this.authToken.token
}
})
.then(response => response.json())
.then(json => this.habits = json)
},
I have proven that the right token is sent and received. I am assuming because CURL works that the Django code is working, so that the bug is in the header on the Javascript side.
Can anyone help please?
There was a missing component in the HTTP header, it needed to have "cedentials: 'included'"
The final header was :
fetch('http://127.0.0.1:8000/api/habit/?format=json',{
method: 'GET',
headers: {
'Accept': '*/*',
'Content-Type': 'application/json',
'Authorization': 'Token '+this.authToken.token
},
credentials: 'include'
})

Uploading file via PUT method in react-native

I am trying to upload file(image) from my react-native app to backend server. The RESTFUL backend server accepts file send via PUT method on a specific url. I am stuck on react-native trying to find the proper way to send file via PUT method.
I am trying to replicate behavior of
curl -X PUT -T "/path/to/file" "http://myputserver.com/puturl.tmp"
I found XMLHttpRequest method of doing this on a browser but won't work on react-native. Have anyone gone through this please help!!!
fetch('https://mywebsite.com/endpoint/', {
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
})
.then((response) => response.json())
.then((responseJson) => {
alert(responseJson)
})
.catch((error) => {
console.error(error)
})
reference
reference 2
Fetch
Use the fetch api, which is supported by React Native.
Below is an example of the official documentation.
Fetch supports PUT, according to the specs.
fetch('https://mywebsite.com/endpoint/', {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
You can use the PUT like the answer above. You might be missing the 'Content-Type': 'multipart/form-data;'.
const config = {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data;',
'Authorization': 'Bearer ' + 'SECRET_OAUTH2_TOKEN_IF_AUTH',
},
body: data,
}
Some more information in this blog post:
http://snowball.digital/Blog/Uploading-Images-in-React-Native

Categories