I am a beginner and been playing around with some js code.
First I would like to know what this line of code exactly does. Let's assume n is some variable. My understanding was, that it sends a http request to herokuapp with the data of interest "n". How is that data incorporated?
const Http = new XMLHttpRequest();
const url='https://myapp.herokuapp.com/?data='+n;
Http.open("GET", url);
Http.send();
What is the most simple way to accept and log the data n in my heroku app?
Thanks in advance!
The code above sends a HTTP GET request to the application running at myapp.herokuapp.com passing a parameter called data with whatever value the variable n holds.
On Heroku typically you deploy an application (service) than can listen and process HTTP requests. You can use any language (JS, Python, Java, etc..) since they all are suitable to implement a web service.
Using NodeJS you would do something like:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
const data = req.query.data // grab parameter
console.log(`Value of data is ${data}`);
res
.status(200)
.send('Ok')
.end();
});
// Start the server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
});
Checkout NodeJS on Heroku to see how you setup and deploy a NodeJS application.
Related
I’m a long term programmer, but haven’t used nodejs much in my code. Now I need to use it in my current code and I’ve ran into a problem that I can’t seem to figure out myself, I have googled a lot but nothing seem to fix it.
I am trying to get my website to connect to the nodejs server running on same host.
If I visit the url in my browser, it works fine (http://localhost:6857/socket.io/?EIO=4&transport=polling) and I see this respond
0{"sid":"s_v860SbNO4toknPAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}
But when I try to connect thru the website, I just get
GET http://localhost:6857/socket.io/?EIO=3&transport=polling&t=N_gL_HZ net::ERR_CONNECTION_REFUSED
Can someone guide my in the right direction for how to fix this, so I can begin using nodejs inside my website?
This is my server.js
// use express
var express = require("express");
// create instance of express
var app = express();
// use http with instance of express
var http = require("http").createServer(app);
// start the server
var port = 6857;
http.listen(port, '0.0.0.0', function () {
console.log("Listening to port " + port);
});
// create socket instance with http
var io = require("socket.io")(http);
// add listener for new connection
io.on("connection", function (socket) {
// this is socket for each user
console.log("User connected", socket.id);
});
io.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
And this is my JS code inside my website
<script>
var server = "http://localhost:6857/";
var io = io(server);
</script>
Socket IO requires you to enable CORS explicitly - Thus why you get the error stated above.
To enable CORS, please see the following link
My main server.js File
const koa = require("koa");
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
const app = new koa();
var router = new Router();
// app.use(bodyParser({ enableTypes: ["json", "text"] }));
// I have also tried passing enabletypes parameteres but it still is not working..
app.use(bodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
router.post("/", async (ctx) => {
console.log(ctx);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server started on port no ${PORT}`));
When i hit this router.post("/") end point ... just for the purpose to see my context object i console logged the context object and it shows the following in the console when I hit this endpoint using postman (i am send JSON body in the request)
My postman request
How do I access my body (JSON object) ?
To access your body object, try the following:
const body = ctx.request.body;
Secondly: because in one of the comments there was a note, why you get a 404. I guess this is because in your route you are not returning anything. So your route could look like:
router.post("/", async (ctx) => {
const body = ctx.request.body;
console.log(body);
return (true) // or whatever you want to return to the client
});
I'd suggest using something to return i.e. if you return nothing you are going to get a 404 with Koa. Just set the body of the ctx i.e. ctx.body="something here".
Other than that depending on what you are using in the app to hit it Postman may work slightly different and pass additional headers etc. I've run into this a handful of times using Thunder Client on VS Code where it works when poking it but in the app something is slightly off. I've ONLY run into this with Koa and never express so might be worth checking and logging along the way WITHIN the app.
I want to be able to send some kind of progress data from a long running async function running on a node express server when a client requests for the data and waits for its completion.
const express = require('express');
const app = express();
const port = process.env.PORT;
app.get('/', (req, res) => {
// Send data to client
(async () => {
await someFunc();
})();
})
Assuming someFunc() is responsible to return the progress data and the final response to the client.
Well, you can't do that since the first response will end the HTTP request (end the connection).
What you looking for is WebSocket, with WebSocket you can keep pushing data to the client since it maintains the connection
check https://www.npmjs.com/package/websocket
So I have this long confusion about creating webhook API for my local app. This project is for learning purpose only so I need to understand what is the difference between simple REST API and webhook, in terms of implementation. I know the difference in terms of working but I can't get the technical difference.
For example, when I use Firebase in my web app and use the real-time database to get the updated values on the client-side, it works seamlessly and I don't need to make the POST or GET call every second or minute. It gets updated instantaneously. I know they might not be using webhook as such but rather using web-socket to keep the connection open between a client web app.
Okay now back to the webhook on the local machine - How can I create my own webhook server where the client can hook to the endpoint and get updates automatically.
Let me share some code
WebHook NodeJS server
// Require express and body-parser
const express = require("express")
const bodyParser = require("body-parser")
// Initialize express and define a port
const app = express()
const PORT = 3000
// Tell express to use body-parser's JSON parsing
app.use(bodyParser.json())
// Start express on the defined port
app.listen(PORT, () => console.log(`🚀 Server running on port ${PORT}`))
app.use(bodyParser.json())
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
var headers = {};
// headers["Access-Control-Allow-Origin"] = req.headers.origin;
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = false;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
res.writeHead(200, headers);
res.end();
} else {
next();
}
})
const processSomething = callback => {
setTimeout(callback, 1000);
}
app.post("/hook", (req, res) => {
console.log(req.body) // Call your action on the request here
processSomething(() => {
res.status(200).send({
id: "ABC123",
message: "New record added!"
});
});
})
Web client running
index.html -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webhook Test Client</title>
</head>
<body>
<h1>Hello World</h1>
<div class="result">Data</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$.post("http://localhost:3000/hook", function (data) {
console.log("data -- >",data);
$(".result").html("data -- > " + data);
});
</script>
</body>
</html>
nodejs to server the page -
const express = require('express'),
app = express(),
server = app.listen(1000);
app.use(express.static('public'));
console.log("server running...");
I have seen so many tutorials on Medium or other tech blogs but they mostly talk about connecting to webhook API hosted somewhere on a webserver that they have built as service or something.
So far I have understood and not understood is that.
I can't make webhook API call from the web client.
Only nodejs client-server can make webhook calls to the webhook endpoint. What I mean by this is - in my example webhook can't be called from HTML page but server serving that page can make the call. Maybe I am wrong.
Webhook is not so different from REST API.
Webhook is not made for the web client.
I will update this question as I get relevant replies and testing them.
Why I am interested in webhook because I wanted to create an API where the user doesn't have to make calls to an API to get an update but at the same time the API can be used from the web client, like firebase but avoid WebSocket at the same time. Or can I avoid WebSocket?
Edit: - So I got confirmation on webhooks are designed for server-to-server communication.
Most of the demos available online are using githud, discord, zapier, etc to create webhooks. Can you please share where we can just make custom webhooks without using third party libs ?
I have a node.js application which I use to interact with a REST API provided by another server. I would like to expose a web interface (html + css + javascript) using express.js in order to control the first application.
How can I let the browser talk to the server and let it make node.js actions like using http from that machine or writing to its filesystem? I tried using XMLHttpRequest, but HTTP requests are sent by my local PC instead of from my server.
The only solution I found is using XMLHttpRequest in the javascript of my web interface to invoke some middleware functions on my server, but I had some problems: when I make POST requests, I cannot read data from server. I used FormData and its append method to make the "body" of the POST request, then used body-parser in express to read that body, but it turns out to be always empty. Also tried changing the 'Content-Type' of the header.
Any suggestions? Any better solution than mine (I think it is not efficient)?
As pointed by Jonas, using node server as proxy would be the right approach.
I'm providing sample code for both frontend as well as backend app. Hope this helps you.
Frontend App Code
<html>
<head>
<script type="text/javascript">
function sendData(data) {
if (!data) {
// lets define some dummy data for testing
data = { somekey: "somevalue", anotherkey: "anothervalues" };
}
var XHR = new XMLHttpRequest();
var FD = new FormData();
// Push our data into our FormData object
for (name in data) {
FD.append(name, data[name]);
}
// Define what happens on successful data submission
XHR.addEventListener("load", function(event) {
alert("Yeah! Data sent and response loaded.");
alert(event.target.responseText);
});
// Define what happens in case of error
XHR.addEventListener("error", function(event) {
alert("Oops! Something went wrong.");
});
// Set up our request
XHR.open("POST", "http://path/to/your/nodejs/server/app");
// Send our FormData object; HTTP headers are set automatically
XHR.send(FD);
}
</script>
</head>
<body>
<button onclick="sendData()">Send Test Request to the Server</button>
</body>
</html>
Backend App code
const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => res.send('Yeah! Server is UP! Post some data'));
app.post('/', (req, res) => {
// You'll see the posted data in req.body, simply for testing purpose return it back to the calling user
res.json(req.body || {});
});
const server = http.createServer(app);
server.listen(3000);
server.on('error', console.error);
server.on('listening', () => console.log('Listening on 3000'));
process.on('exit', (code) => console.warn('Server terminated with code=' + code));
Please note that for this backend app to run, you must have installed following npm packages: express, body-parser