JavaScript fetch request body parameters not received - javascript

Context:
I am trying to send a put request to a server using JavaScript and fetch from an html file I'm writing.
Problem:
The request I made is working in Insomnia, but when I try to send it from an html it isn't properly received. The code was generated by Insomnia also.
When I send it from the html the request is sent, and I get an ok back, but the server doesn't complete the task in the request, leading me to believe that it wasn't received or I missed something.
When trying to send the request, the console shows a response, that says "ok", 200, etc., but also has a "bodyUsed: false" part.
The function generated by Insomnia:
fetch("url", {
"method": "PUT",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"body": {
"name": "name",
"desc": "description"
}
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
Question(s):
Is there anything wrong with the code? How does the server receive the request but not the body? Does the "bodyUsed: false" message mean that the request's body was ignored for some reason? Could this all be the server's fault?
Disclaimer:
I am a bit new to web development, so forgive me if I miss some obvious point.

If you keep "content-type": "application/x-www-form-urlencoded" and your server is configured that way, you should send your data using a FormData like this:
var formData = new FormData();
formData.append('name', 'Chris');
formData.append('descr', 'description');
fetch("url", {
"method": "PUT",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"body": formData
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});

try this
let formData = new FormData();
formData.append('name', 'name value');
formData.append('desc', 'description value');
fetch('url', {
method: 'POST',
credentials: 'same-origin',
body: formData
}).then(rawResponse => rawResponse.json())// or rawResponse.text() to get simple string
.catch(error => {
console.log(error);
})
.then(response => {
console.log(response);
});

Related

Javascript Fetch : Error Unexpected token < in JSON at position 0

I am sending a POST request to my Django view. When I run the code in local it works but when I run it on my apache server it gives me a 500 error. Could you help me, please !!
This is my code:
form.addEventListener('submit', e=>{
e.preventDefault()
const baseInput = document.querySelector('#inputbaseform0')
if(baseInput.value !== null){
$('#loadMe').modal('show');
let data = {}
data['base'] = baseInput.value
data['tiempo'] =tiempo.value
data['otros'] =otros.value
let url = "{% url 'cal' %}";
fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"X-CSRFToken": document.querySelector('#form0 input').value,
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).then(function(response){
return response.json();
}).then(function(data){
console.log('ERROR: ', data.error)
baseData = parseFloat(data.base).toFixed(2)
deducir.value = data.porciento//porciento
$('#loadMe').modal('hide');
}).catch(function (e){
console.log('Error', e);
$('#loadMe').modal('hide');
})
}
})
})
Your problem is not in your js code. This code does exactly what you want, trying to parse response data as json. But your django view returns the 500 error page for some reason, and this page is html starting with "<".
Logs can tell you why your django view throws an exception.

Uploading image file with formData and Axios

so i want to upload an image to a server which doesn't accept json payloads, but rather formData.
What i'm doing is
var bodyFormData = new FormData();
bodyFormData.set("access_token", globalState.access_token);
bodyFormData.set("listing_id", 2);
bodyFormData.append("image", Cookies.get("listingCover"));
but after this if i console.log(bodyFormData) it returns an empty object? Instead if i console.log(...bodyFormData) it returns 3 saperate arrays of each formdata that i set above. I want to be able to send it as bodyFormData in the body of the request like shown below. How do i do that?
axios({
method,
url: url,
data: bodyFormData,
headers: { "Content-Type": "multipart/form-data" },
})
Use FormData.entries() to console.log to see whats stored in your formData
You can not simply console.log(bodyFormData) it will NOT return anything.
Run snippet below.
var bodyFormData = new FormData();
bodyFormData.set("access_token", 'globalState.access_token');
bodyFormData.set("listing_id", 2);
bodyFormData.append("image", 'Cookies.get("listingCover")');
//Loop througt formData
for (var data of bodyFormData.entries()) {
console.log(data[0]+ ', ' + data[1]);
}
You do no have any method when you are doing axios You need to set your method to post like below to send your bodyFormData
Edit: Working Demo: https://jsfiddle.net/mxkLejrf/
=> In the demo you can see dev tools -> network the bodyFormData is being sent via POST
axios({
method: 'post',
url: 'someEndPointUrl',
data: bodyFormData,
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(function(response) {
// success
console.log(response);
})
.catch(function(response) {
// error
console.log(response);
});

React Native network error in POST request when adding a body

it's me again.
I'm learning react native, for now im trying to upload a file, the api is already tested using postman and it does work so I wrote this code:
import * as DocumentPicker from 'expo-document-picker';
async login () {
let response = await DocumentPicker.getDocumentAsync({type: '*/*'})
const data = new FormData();
data.append('file', response)
// Fetch attempt ----------------------------------------
fetch("http://192.168.0.3:8000/api/file", {
method: "POST",
headers:{
"Content-Type": "application/x-www-form-urlencoded",
},
body: data
})
.then(response => response.json())
.then(response => {
console.log("upload succes", response);
})
.catch(error => {
console.log("upload error", error, JSON.stringify(error));
});
// Axios attempt ----------------------------------------
axios.post('http://192.168.0.3:8000/api/file', data, { headers:{ "Content-Type": "application/x-www-form-urlencoded"} } )
.then(res => {
console.log("goddaamittt wooork", res)
})
.catch(error => {
console.log("error", error, JSON.stringify(error))
});
}
When I remove the body and headers from that request it actually returns what the api should return when you try to POST to it without a 'file', some message "{'fileName': 'A file is required'}" but adding it to it I get a network error, the error I get when using fetch it:
upload error [TypeError: Network request failed] {"line":24646,"column":31,"sourceURL":"http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=android&dev=true&minify=false&hot=false"}
when it reaches the axios attempt it says something like this:
[Unhandled promise rejection: TypeError: Network request failed]
I tried everything I knew, I need some help!
Idk if it is important but here is what DocumentPicker returns when I pick a file:
Object {
"name": "FB_IMG_1573232116651.jpg",
"size": 32482,
"type": "success",
"uri": "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252Fjsonplaceholder-bcb4c1c6-b37d-4634-99a5-3410d9b8654e/DocumentPicker/db8d78dd-2587-40e4-aed9-656c36df29f4.jpg",
}
This is the error I get when I remove the body from the axios request
error [Error: Request failed with status code 400] {"config":{"transformRequest":{},"transformResponse":{},"headers":{"Accept":"application/json, text/plain, /"},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"method":"post","url":"http://192.168.0.3:8000/api/file"},"response":{"data":{"message":"File is required"},"status":400,"headers":{"map":{"cache-control":"public, max-age=0","x-robots-tag":"noindex","x-debug-token-link":"http://192.168.0.3:8000/_profiler/54e68c","x-debug-token":"54e68c","link":"http://192.168.0.3:8000/api/docs.jsonld; rel=\"http://www.w3.org/ns/hydra/core#apiDocumentation\"","content-type":"application/json","x-powered-by":"PHP/7.2.4","connection":"close","date":"Fri, 08 Nov 2019 17:54:12 GMT","host":"192.168.0.3:8000"}},"config":{"transformRequest":{},"transformResponse":{},"headers":{"Accept":"application/json, text/plain, /"},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"method":"post","url":"http://192.168.0.3:8000/api/file"},"request":{"url":"http://192.168.0.3:8000/api/file","credentials":"omit","headers":{"map":{"accept":"application/json, text/plain, /"}},"method":"POST","mode":null,"referrer":null,"_bodyText":""}},"line":178773,"column":26,"sourceURL":"http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=android&dev=true&minify=false&hot=false"}
It was such a dump solution, it took me hours to find this:
When I get the file from DocumentPicker I had to add the type of the file because DocumentPicker return an odd type called "success", when I changed it to 'image/jpeg' it worked :D its not a solution at all because I will need to find a way to know what type of file is each file a user chooses, anyways, this code works c:
let response = await DocumentPicker.getDocumentAsync({type: 'image/jpeg'})
response.type = 'image/jpeg' // <- lasdfkasdfaslfkfsdkdsaf
const data = new FormData();
data.append('file', response);
axios.post('http://192.168.0.3:8000/api/file', data , {headers: { 'Content-type': 'application/x-www-form-urlencoded' }} )
.then(res => {
console.log("gooosh", res.data)
})
.catch(error => {
console.log("error", error, JSON.stringify(error))
});
you should try to modify the content-type to
fetch("http://192.168.0.3:8000/api/file", {
method: "POST",
headers:{
'Content-Type': 'multipart/form-data',
},
body: data
})
and for the form-url-urlencoded, the fetch is not supported. you have to push it by yourself.you can see this answer.

Add parameters to post request using js on client side

I'm developing a "TODO" app using node.js and mongodb.
I'm trying to post a new task from the client but I didn't success to pass parameters to the server and from there to the database.
Client code:
<script>
function addData(item, url) {
var text = document.getElementById("myTask").value;
return fetch('/todos',{
method: 'post',
body: text
}).then(response => response.json())
.then(data => console.log(data));
}
</script>
Server code:
app.post('/todos',(req,res) =>{
console.log("\n\n req.body is: \n\n",req.body);
var todo = new Todo({
text: req.body.text});
todo.save().then((doc) =>{
res.send(doc);
console.log(JSON.stringify(doc,undefined,2));
},(err) =>{
res.status(400).send(err); //400 = unable to connect
console.log("Unable to save todo.\n\n\n" , err);
});
});
And the problem is that the client doesn't send the body to the server,
and the body is null on the server side:
See the logs here
(as you can see: req.body = {})
In the js code, I tried to pass the body parameter but I guess I did something wrong so I want to know the best way to pass parameters back to the server (not only the body but text, time and etc)
Thank in advance,
Sagiv
I think that you are missing something. Try to use name of param
body: JSON.stringify({data: text})
OR
read here Fetch: POST json data
I used this code:
(async () => {
const rawResponse = await fetch('https://httpbin.org/post', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({a: 1, b: 'Textual content'})
});
const content = await rawResponse.json();
console.log(content);
})();
and now I succeeded to pass data to the request.
Thanks everybody

React Native - Fetch POST not working

I am having huge troubles getting my fetch POST calls to work on iOS. My standard Fetch calls work and the Fetch POST calls work fine on android but not iOS.
The error that comes up is "Possible Unhandled Promise Rejection (id: 0): Unexpected token < in JSON at position 0"
It actually saves the post data to my server but throws that error.
I tried debugging the network request using GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest; before the API call coupled with using CORS in my chrome debug tools. From there I can see that it is making two post calls one after the other. The first one has type "OPTIONS" while the second one has type "POST". It should probably be noted that the call works in the App while using CORS and the line of code above.
I'm very confused and have exhausted all avenues.
My code im using for refrence is as follows.
return fetch(url,{
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then((res) => res.json());
If JSON.stringify is not working, then try to use FormData.
import FormData from 'FormData';
var formData = new FormData();
formData.append('key1', 'value');
formData.append('key2', 'value');
let postData = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
}
fetch(api_url, postData)
.then((response) => response.json())
.then((responseJson) => { console.log('response:', responseJson); })
.catch((error) => { console.error(error); });
You use the following code for POST request in react native easily. You need to only
replace the parameter name and value and your URL only.
var details = {
'userName': 'test#gmail.com',
'password': 'Password!',
'grant_type': 'password'
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('http://identity.azurewebsites.net' + '/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formBody
}).
.then((response) => response.json())
.then((responseData) => {
console.log("Response:",responseData);
}).catch((error) => {
Alert.alert('problem while adding data');
})
.done();
I would guess the response you are receiving is in HTML. Try:
console.warn(xhr.responseText)
Then look at the response.
Also, IOS requires HTTPS.
Edit: Possible duplicate: "SyntaxError: Unexpected token < in JSON at position 0" in React App
Here is an example with date that works for me!
The trick was the "=" equal and "&" sign and has to be in a string format in the body object.
Find a way to create that string and pass it to the body.
====================================
fetch('/auth/newdate/', {
method: 'POST',
mode: 'cors',
redirect: 'follow',
body: "start="+start.toLocaleString()+"&end="+end.toLocaleString()+"",
headers: new Headers({
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
})
}).then(function(response) {
/* handle response */
if(response.ok) {
response.json().then(function(json) {
let releasedate = json;
//sucess do something with places
console.log(releasedate);
});
} else {
console.log('Network failed with response ' + response.status + ': ' + response.statusText);
}
}).catch(function(resp){ console.log(resp) });
server node.js?
npm i cors --save
var cors = require('cors');
app.use(cors());
res.header("Access-Control-Allow-Origin: *");

Categories

Resources