Im having issues with a POST with "whatwg-fetch" the response is returnin as 200 but no data is passing.
this is the code on the server...
app.post('/promo', function(request, response) {
response.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
var promo = new PromoItem();
promo.imgUrl = request.body.imgUrl;
promo.name = request.body.name;
promo.description = request.body.description;
promo.category = request.body.category;
console.log('----------');
console.log(promo.name);
console.log(request.body.name);
console.log('----------');
promo.save(function(err, savedPromo) {
if (err) {
responde.status(500).send({
error: "Something happened, promo not saved !"
});
} else {
response.status(200).send("Success !");
}
});
});
both promo.name and request.body.name are returning as undefined.
The code on the client..
setPromo = () => {
const options = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
mode: 'no-cors',
body: JSON.stringify({
"imgUrl": "http://via.placeholder.com/900x200",
"name": "MI POST",
"description": "MI PRIMER POST",
"category": "Salud"
})
};
fetch('http://localhost:3010/promo', options).then(function(response) {
console.log('Status', response.status);
})
}
have manipulated the options with different values but still the same result.
any ideas?
thanks
It's possible that the data is not being parsed. In Express, POST bodies can be parsed by body-parser. There are usage examples on the Express website. Essentially, you can use the body-parser middleware like this:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
It can also be used on a per-route basis:
app.post('/promo', bodyParser.json(), function(request, response) { //...
If you are using a version of Express >= 4.16.0, bodyParser.json is available as express.json. (source)
Related
I'm working on integrating spotify and I'm making my own api. I can't understand why my request is not working. It works fine in python but not when I use express.
I get this response body :
{"error":"unsupported_grant_type","error_description":"grant_type must be client_credentials, authorization_code or refresh_token"}
Express :
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var fetch = require('node-fetch');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }))
app.listen(80);
app.post('/v1/spotify/api/token', function(req, res) {
let body = req.body
let redirect_uri = body.redirect_uri
let code = body.code
let data = {
grant_type:'authorization_code',
redirect_uri:redirect_uri,
code:code
}
fetch('https://accounts.spotify.com/api/token', {
method: 'POST',
headers: {
'Authorization':'Basic *client_id:client_secret*',
'Content-Type':'application/x-www-form-urlencoded'
},
body: JSON.stringify(data)
}).then(r => r.json().then(data => res.send(data)))
});
Python:
r = requests.post("https://accounts.spotify.com/api/token",
data={
"grant_type":"authorization_code",
"redirect_uri":*redirect_uri*,
"code":*code*
},
headers = {
"Authorization": "Basic *client_id:client_secret*",
'Content-Type':'application/x-www-form-urlencoded'}
)
In your script of Node.js, data is sent as a string value. So how about this modification?
Modified script
Please modify the object of data as follows and try again.
// Below script was added.
const {URLSearchParams} = require('url');
const data = new URLSearchParams();
data.append("grant_type", "authorization_code");
data.append("redirect_uri", redirect_uri);
data.append("code", code);
fetch('https://accounts.spotify.com/api/token', {
method: 'POST',
headers: {
'Authorization':'Basic *client_id:client_secret*',
'Content-Type':'application/x-www-form-urlencoded'
},
body: data // Modified
}).then(r => r.json().then(data => res.send(data)))
Reference:
Post with form parameters of node-fetch
If this didn't work, I apologize.
I had to put the client_id and client_secret in the body and not in Authorization header.
try {
const body = {
grant_type: "client_credentials",
client_id: <YOUR_ID>,
client_secret: <YOUR_SECRET>,
};
const response = await fetch("https://accounts.spotify.com/api/token", {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams(body),
});
console.log({ response });
} catch (err) {
console.log({ err });
}
Please help me with the below POST request that I'm trying to make. Below is the code snippet.
const express = require("express");
const bodyParser = require("body-parser");
//const request = require("request");
const https = require("https");
const request = require('request-promise');
const app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static("public"));
app.get("/", function(req, res){
res.sendFile(__dirname + "/test.html");
});
const data = {
"some_header":{
"name":"xxxxx"
}
};
const jsonData = JSON.stringify(data);
console.log(jsonData);
app.post("/post", function(req, res){
const url = "xxxxxxxxxxxx";
const options = {
method: "POST",
body: data,
json: true,
headers: {
ContentType: "application/json",
Authorization: "nhgjgjhgjghjghj"
}
}
const request = https.request(url, options, function(response) {
if (response.statusCode === 200) {
// res.send("success");
console.log("success");
} else {
//res.send("Failed");
console.log("failure");
}
response.on("data", function(data) {
console.log(JSON.parse(data));
})
})
request.write(jsonData);
request.end();
});
app.listen(process.env.PORT || 3000, function() {
console.log("The app is up and running on Port 3000");
});
I'm getting 200OK response from the external server, but unable to post the data. When I logged the response data from the server, I received this success
{ require_login: true }
"Success" is the console log message. require_login: true is the response I'm getting from the server. where am I going wrong?
Try to add Basic before you api key. Also, if you are using base64, then check that original string is right one and should be something like: login:password
headers: {
ContentType: "application/json",
Authorization: "Basic BAsE64Format or api:key or login:password"
}
headers: { "Content-type": "application/json", Authorization: 'Basic ' + Buffer.from('CtB2HZwaRdGggr1g4K').toString('base64') }
enclosing the content-type with quotes and converting the API key to base 64 did the trick
I'm setting up an ajax client with a dummy server (just to test). I've managed to resolve the cors issue it seems, but the response as seen from the ajax client is undefined. When I get at the same URL using just a browser thought, it displays the object properly.
// server-side
var express = require('express');
var router = express.Router();
var cors = require('cors');
router.use(cors());
var data = [
{"id": 1, "message": 'first object'},
{"id": 2, "message": 'second object'},
{"id": 3, "message": 'third object'}
];
router.get('/', (req, res, next) => {
console.log("building response body");
res.json(data);
});
// client-side
function fetcher() {
console.log("fetch from:" + rootUrl + arrayEndpoint);
fetch(rootUrl + arrayEndpoint, {
mode: "cors",
method: "GET",
headers: {
"Content-Type": "application/json"
}
})
.then((response) => {
console.log(response);
console.log("response: " + response.body);
})
.catch((error) => {
console.log("error: " + error);
});
}
The response printed to the console of the client:
Response { type: "cors", url: "https://angry-badger-63.localtunnel.me/getArray/", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers, bodyUsed: false }
undefined
And on the browser:
[{"id":1,"message":"first object"},{"id":2,"message":"second object"},{"id":3,"message":"third object"}]
So I'm pretty sure my server-side is fine (it does send what I expect to the browser and how complicated can resp.json(object) really be?), but apparently something about the ajax client I'm not seein. What's wrong with it?
Taking into account SLak's comment, fetch doesn't have resp.body, which I sort just had assumed. Huge blind spot there.
That revealed another issue - which was that resp.json() (which would be the actual way to handle it) returns a promise, which I wasn't handling. Actually it seems the parsing of the response (whether with .json() or with .text()) returns a promise in general. I'm still not really getting the array proper, but to keep things on topic here's a corrected snippet to parse a generic json object:
//client.js
function fetcher() {
console.log("fetch from:" + rootUrl + arrayEndpoint);
fetch(rootUrl + arrayEndpoint,{
mode: "cors",
method: "GET",
headers: {"Content-Type": "application/json"}
})
.then(function(response) {
response.json()
.then(function (data) {
console.log(data);
});
})
.catch(error => console.log("error:" + error));
}
//server.js
var express = require('express');
var router = express.Router();
var cors = require('cors');
/* GET users listing. */
router.use(cors());
var data = {"1":{"id":1, "message": 'first object'},
"2":{"id":2, "message": 'second object'},
"3":{"id":3, "message": 'third object'}};
router.get('/', function(req, res, next) {
console.log("building response body")
console.log(data)
res.json(data);
});
I'm trying to use GoToMeeting's API and making a POST request to create a meeting. At the moment, I'm just trying to hardcode the body of the meeting and send headers but I'm receiving and I'm invalid JSON error and not sure why. Here's the code for that route:
app.post('/new-meeting', (req, res) => {
const headers = {
'Content-Type': 'application/json',
Accept: 'application / json',
Authorization: 'OAuth oauth_token=' + originalToken
};
console.log('-----------------------------------------------------------')
console.log('Acess Token:');
console.log('OAuth oauth_token=' + originalToken);
console.log('-----------------------------------------------------------')
const meetingBody = {
subject: 'string',
starttime: '2018-03-20T08:15:30-05:00',
endtime: '2018-03-20T09:15:30-05:00',
passwordrequired: true,
conferencecallinfo: 'string',
timezonekey: 'string',
meetingtype: 'immediate'
};
return fetch('https://api.getgo.com/G2M/rest/meetings', {
method: 'POST',
body: meetingBody,
headers: headers
}).then(response => {
console.log('response:');
console.log(response);
response
.json()
.then(json => {
res.send(json);
console.log(req.headers);
})
.catch(err => {
console.log(err);
});
});
});
When I hit that router, I get the following error:
{
"error": {
"resource": "/rest/meetings",
"message": "invalid json"
}
}
Any advice would be appreciated!
tl;dr
You are passing fetch a value for the body represented by a JavaScript object. It is converting it to a string by (implicitly) calling its .toString() method. This doesn't give you JSON. The API you are calling then complains and tells you that it isn't JSON.
You need to convert your object to JSON using:
body: JSON.stringify(meetingBody),
Test case
This demonstrates the problem and the solution.
Server
This is designed to be a very primitive and incomplete mock of GoToMeeting's API. It just echos back the request body.
const express = require("express");
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.text({ type: "*/*" }));
app.post("/", (req, res) => {
console.log(req.body);
res.send(req.body)
});
app.listen(7070, () => console.log('Example app listening on port 7070!'))
Client
This represents your code, but with the Express server stripped out. Only the code relevant for sending the request to GoToMeeting's API is preserved.
const url = "http://localhost:7070/";
const fetch = require("node-fetch");
const headers = {
'Content-Type': 'application/json',
Accept: 'application / json',
Authorization: 'OAuth oauth_token=foobarbaz'
};
const meetingBody = {
subject: 'string',
starttime: '2018-03-20T08:15:30-05:00',
endtime: '2018-03-20T09:15:30-05:00',
passwordrequired: true,
conferencecallinfo: 'string',
timezonekey: 'string',
meetingtype: 'immediate'
};
fetch(url, {
method: 'POST',
body: meetingBody,
headers: headers
})
.then(res => res.text())
.then(body => console.log(body));
Results of running the test case
The logs of both server and client show:
[object Object]
This is what you get when you call meetingBody.toString().
If you change the code as described at the top of this answer, you get:
{"subject":"string","starttime":"2018-03-20T08:15:30-05:00","endtime":"2018-03-20T09:15:30-05:00","passwordrequired":true,"conferencecallinfo":"string","timezonekey":"string","meetingtype":"immediate"}
This is JSON, which is what the API is expecting.
Aside
MIME types do not have spaces in them. Accept: 'application / json', should be Accept: 'application/json',. This probably isn't causing you any problems though.
I believe the header is incorrect.
You need 'Accept: application/json' without space.
I am writing a simple node.js for a REST API call to create object through POST method and get the response code. But while running the script I get "0 passing" .
Here is my code:
var request = require("request");
var options = { method: 'POST',
url: 'https://example.org',
headers:
{ 'content-type': 'application/vnd.nativ.mio.v1+json',
authorization: 'Basic hashedTokenHere' },
//body: '{\n\n"name": "My JS TEST",\n"type": "media-asset"\n\n}'
};
request(options, function (error, response, body) {
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
Can anyone help to to run it successfully and get the response code?
Thanks!
I calling my local API hope this will make thing get clear. It's work for me
This my API
var express = require('express')
var router = express.Router()
var bodyParser = require('body-parser');
var app=express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/api',function(req,res)
{
res.status(200).send(req.body.name+"hi");
})
app.listen(8080,function(){
console.log("start");
})
Now, through Request, i will request this post method
var request = require('request');
// Set the headers
var headers = {
'User-Agent': 'Super Agent/0.0.1',
'Content-type': 'application/json',
'Authorization': 'Basic ' + auth,
}
var postData = {
name: 'test',
value: 'test'
}
// Configure the request
var options = {
url: 'http://127.0.0.1:8080/api',
method: 'POST',
json: true,
headers: headers,
body: postData
}
// Start the request
request(options, function (error, response, body) {
// Print out the response body and head
console.log("body = "+body+" head= "+response.statusCode)
}
})