Why data not getting posted to the route? - node.js

I have an application wherein after getting the data from user, I am posting it to the /create
route.
However upon making a post request, it gives me error:
POST http://localhost:5000/create 404 (Not Found)
The code for making post request:
submitbtn.addEventListener('click', (e) => {
e.preventDefault();
const data=validateForm();
if (data) {
postData(data);
console.log("submitted");
}
})
async function postData(data) {
await fetch('http://localhost:5000/create', {
method: 'POST',
body: {
title: `${data.title}`, content: `${data.text}`
},
headers: {
'Content-Type': 'application/json'
}
})
}
Handling the post request on my server:
const express=require('express');
const app= express();
const router=express.Router();
const News=require('./news/news');
app.use(express.static('./public'));
router.post('/create',(req,res)=>{
res.send("Successful");
})
app.listen(5000,()=>{
console.log("Server listening on 5000 port");
})

Related

Can't make a successful Authorization request from Axios request to third-party API

I have been dealing with this issue where I am attempting to make a get request to a third-party API using Axios in my Node.js server. The endpoint requires a username and password which I am passing along as follows:
export const getStream = async(req, res) => {
let conn = createConnection(config);
let query = `SELECT * FROM cameras WHERE id = ${req.params.id}`
conn.connect();
conn.query(query, async (error, rows, _) => {
const camera = rows[0];
const {ip, user, pass} = camera;
if (error) {
return res.json({ "status": "failure", "error": error });
}
const tok = `${user}:${pass}`;
const userPass = Buffer.from(tok)
const base64data = userPass.toString('base64');
const basic = `Basic ${base64data}`;
const result = await axios({
method: 'get',
url: `<API URL>`,
headers: {
'Authorization': basic,
'Content-Type': 'multipart/x-mixed-replace; boundary=--myboundary'
},
auth: {username: user, password: pass}
})
res.json(result)
});
conn.end();
}
I am then calling this endpoint in my React front-end as such:
const getStream = async () => {
try {
const result = await publicRequest.get(`camera/getStream/${id}`)
console.log(result)
} catch (error) {
console.error(error)
}
}
Each time I make this request, my node server crashes and I get a 401 unauthorized error in my console. It appears that my Authorization header is not getting passed to the server even though everything else gets passed along as so.
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'multipart/x-mixed-replace; boundary=--myboundary',
'User-Agent': 'axios/0.26.1'
},
method: 'get',
url: '<url>',
auth: { username: '<username>', password: '<password>' },
data: undefined
For extra information, this is how my node server is setup
import express, { urlencoded, json } from 'express';
import userRoute from './routes/userRoute.js';
import cameraRoute from './routes/cameraRoute.js';
import cors from 'cors';
const app = express();
app.use(cors());
app.options('*', cors());
app.use(json())
app.use(urlencoded({ extended: true }));
app.use(express.static('public'));
app.use('/api/user', userRoute);
app.use('/api/camera', cameraRoute);
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
I have been working on this issue for several days and each time I try something new, I always get a 401 error, and the server crashes.
Any suggestions would be greatly appreciated.

How to send data received from external graphql api with nodejs to frontend (reactjs)

This graphql api I found on the internet is showing cors error when I call it with fetch or apollo client from frontend, So I searched for a solution and I found out that if I call api from server, cors error will go away so I followed a basic tutorial about express and set up one, then call graphql api in my server/index.js
const express = require("express");
const rp = require("request-promise");
rp("https://.../graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `
query {
heroSearchByName(name: "John") {
name
}
}
`,
}),
})
.then((body) => {
console.log(body); // result
})
.catch((err) => {
console.log(err);
});
const PORT = 4000;
const app = express();
console.log(`Server listening on http://localhost:${PORT} ...`);
app.listen(PORT);
Now I get the data back in my terminal but I don't know how to send those data back to my frontend which is in frontend/App.js to show data on my page. Can someone help me with this ? I am quite new to express and graphql so I might be doing it all wrong. Thanks
The idea is something like this:
Frontend makes a request to the backend application.
Backend fetches the data from the GraphQL API and returns it to the client.
So on your express app just build a route
const express = require("express");
const rp = require("request-promise");
app.post('/fetchData', function (req, res) {
rp("https://.../graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `
query {
heroSearchByName(name: "John") {
name
}
}
`,
}),
})
.then((body) => {
res.send(body)
})
.catch((err) => {
console.log(err);
});
})
const PORT = 4000;
const app = express();
console.log(`Server listening on http://localhost:${PORT} ...`);
app.listen(PORT);
``

Node.js: Access JSON body of HTTP POST request with express

I'm making an http post request to my express web server sending dummy data as json. It correctly receives the request and can send back a json object, but for some reason it can't manage to access the post request body.
I'm using this code for express:
const express = require('express');
const app = express();
const port = 3000;
app.post('/test', (req, res) => {
console.log(req.body);
res.json({"some": "thing"});
});
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`)
});
And this is the code of the request:
const req = http.request({
hostname: '127.0.0.1',
port: 3000,
path: '/test',
method: 'POST',
json: {
url: "https://www.nothing.com",
name: "hello"
}
}, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.end()
As you can see I'm running this locally. The client receives a status code 200 and the json {"some": "thing"} sent by the server, but the server gets "undefined" from req.body. I tried using:
headers: {
'Content-Type': 'application/json'
}
body: JSON.stringify({
url: "https://www.nothing.com",
name: "hello"
})
instead of json directly in the request options, but to no avail. I even tried using app.use(express.json()); as someone suggested.
What is the problem?
Apparently the way I was doing the post request was not correct, I had to send the body in a separate line with req.write(), like this:
const http = require('http');
const data = JSON.stringify({ //<--- data to send as body
url: "https://www.nothing.com",
name: "hello"
});
const req = http.request({
hostname: '127.0.0.1',
port: 3000,
path: '/test',
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
}, res => {
console.log(`statusCode: ${res.statusCode}`);
res.on('data', d => {
process.stdout.write(d);
})
})
req.on('error', error => {
console.error(error);
})
req.write(data); //<--- this line
req.end();
You have to add body-parser middleware http://expressjs.com/en/resources/middleware/body-parser.html
req.body empty on posts

Microsoft bot framework webchat hidden secret for direct line -- NODE JS

I need to hide the secret for direct line channel using an HTML webchat, tried this solution but keeps getting me errors while fetching. I got the secret for direct line channel in Azure portal in process.env
Index.js
const dotenv = require('dotenv');
const path = require('path');
const restify = require('restify');
const bodyParser = require('body-parser');
const request = require('request');
const corsMiddleware = require('restify-cors-middleware');
const { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState } = require('botbuilder');
const { EBOT } = require('./eBot');
const ENV_FILE = path.join(__dirname, '.env');
dotenv.config({ path: ENV_FILE || process.env.directLineSecret });
const cors = corsMiddleware({
origins: ['*']
});
const server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
server.use(bodyParser.json({
extended: false
}));
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(`\n${ server.name } listening to ${ server.url }`);
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
});
// Generates a Direct Line token
server.post('/directline/token', (req, res) => {
const options = {
method: 'POST',
uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
headers: {
'Authorization': `Bearer ${process.env.directLineSecret}`
}};
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
res.send({
token: body.token
});
} else {
res.status(500).send('Call to retrieve token from DirectLine failed');
}
});
});
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
await ebot.run(context);
});
});
And webchat.html:
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script>
(async function () {
const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { method: 'POST' });
const webChatToken = await res.json();
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token: webChatToken })
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
</script>
/// UPDATE
The errors:
** Failed to load resource: the server responded with a status of 403 ()
** webchat.js:2 POST https://directline.botframework.com/v3/directline/conversations 403
** webchat.js:2 Uncaught t {message: "ajax error 403", xhr: XMLHttpRequest, request: {…}, status: 403, responseType: "json", …}
What's the way then ?, what am I missing ?
The issue with your particular implementation is, while you have set up an API for generating and serving a token back to Web Chat, you are failing to actually call that endpoint. Instead of
const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { method: 'POST' });
you should have
const res = await fetch('http://localhost:3978/directline/token', { method: 'POST' });
It is this that will make the call to exchange the Direct Line secret for a token and, in turn, will return the token back to your Web Chat instance.
Solved it, the problem was the way the api token function was made, this is the one that worked in order to retrieve the json response from index.js :
server.post('/directline/token', async function(req, res) {
const result = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.DirectLineSecret
}
});
const token = await result.json();
res.send(token);
});
The one I posted in questions was not sending the token response but a huge request ibject instead. Hope it helps !

Issues with nodejs' request and pipe

I'm having an issue with the following code. I'm trying to make a POST request (json) to a URL using pipe but I get the error "write after end" - Internal Server Error. Can someone please help?
test: function( req, res, next) {
var requesty = request.post({
url: dataUrl,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
req.pipe(requesty).on('error', function (error) {
logger.withRequestLog(res, 'error', 'CC Melville Proxy failed!', {
assetUrl: dataUrl,
error: error,
});
next(error);
}).pipe(res);
}
You are getting error because of body: JSON.stringify(body). You can't (also don't need) to pass body as when you are piping raw bytes are being piped as well. Also This middleware should be FIRST as you don't want to use bodyParser etc which will read the stream and make it empty.
Below is an working example where I am proxying my request to one my routes(It can be external also):
const express = require('express');
const app = express();
const request = require('request');
const bodyParser = require('body-parser').json();
const dataUrl = '/employees'
app.use(dataUrl, bodyParser, (req, res)=>{
res.json({
body: req.body || {},
method: req.method,
param: req.params,
headers: req.headers,
url: req.url
});
})
app.use('/', (req, res) => {
var requesty = request({
url: 'http://localhost:8080'+dataUrl,
headers: {
'Content-Type': 'application/json'
},
})
req.pipe(requesty).on('error', function (error) {
console.log('error', 'CC Melville Proxy failed!', {
assetUrl: dataUrl,
error: error,
});
}).pipe(res);
});
app.listen(8080, () => {
console.log('started');
})
Note: You don't need to specify method as it will automatically be passed. From the doc:
You can also pipe() from http.ServerRequest instances, as well as to
http.ServerResponse instances. The HTTP method, headers, and
entity-body data will be sent.

Resources