Post works only after a empty get request - node.js

I wrote a simple server
var express = require('express')
var app = express()
app.post('/', function(req, res){
res.send('hi')
})
app.listen(3000, ()=>{
console.log('listening on 3000')
})
I deployed it on the server post don't responding till I send a get request to it
what is the problem?
It works on localhost but not on the server
Server OS is ubuntu 16.04
I know it's on port 3000 and I know it's a post method so I send post request please don't mention it.
There is no problem with code I think problem is related to Ubuntu. Any changes should I make?

Related

HTTP server gives error when responses some requests

I am making an express.js server to store pictures.
const express = require('express');
const app = express();
app.get('/*', (request, response) =>
{
response.sendFile(__dirname + '/data' + request.path);
});
app.listen(9999);
console.log('Server started on port 9999');
And I have a problem. If I type http://127.0.0.1:9999/vehicles/boats/dinghy.png into browser, I get a picture, but when I type https://127.0.0.1:9999/main/avatar.png I get This site can’t provide a secure connection 127.0.0.1 sent an invalid response. Both files do exist, but one of them is sent correctly, but another one gives an error. What can it be caused by?
Your second request is sent via https. As you're not providing a valid certificate for localhost at your express app, the browser will give you a hint about this.

what is the difference between using Express GET method and HTTPS GET method in the below code?

const express = require("express");
const app = express();
const https = require("https");
app.get("/", function (req, res){
var url = "https://***";
https.get(url, function(response){
console.log(response);
});
res.send("server running");
});
Express is really just a layer on top of http.
I reckon those following links might help you out, this question has been asked.
what's the technical difference between express and http, and connect for that matter
Difference between a server with http.createServer and a server using express in node js
app.get() registers a listener for a specific INCOMING http request path on a local Express server.
https.get() makes an OUTBOUND https request TO some other https server to fetch content from that other server.
And, obviously, the https.get() is using https, not http. The app.get() could be listening for either - it depends upon how the server it is part of is started (as an http server or an https server) which the code you have in your question does not show.

How to make API request from react client to express server running on the Heroku platform

Ive been trying to deploy a Twitch like application using react, redux, node media server and json server module to Heroku. However, I keep running into a issue when trying to connect my react client and express server via a api request, during production.
Im trying to make the actual request through my action creators and by using axios with a base url of http://localhost:4000, however that only works on my local machine.
const response = await streams.get("/streams");
dispatch({ type: FETCH_STREAMS, payload: response.data });
};
You can view my full repo at https://github.com/XorinNebulas/Streamy
You can also view my current deployed version of the site on Heroku at
https://streamy-app.herokuapp.com/
here is my api/server.js file. My express server will be watching on a random port equal to process.env.PORT, so I have no way of knowing how to make a network request via my action creators to that random port during production.
const path = require("path");
const cors = require("cors");
const jsonServer = require("json-server");
const server = jsonServer.create();
const router = jsonServer.router("db.json");
const middlewares = jsonServer.defaults({
static: "../client/build"
});
const PORT = process.env.PORT || 4000;
// Set default middlewares (logger, static, cors and no-cache)
server.use(cors());
server.use(middlewares);
if (process.env.NODE_ENV === "production") {
// Add custom routes before JSON Server router
server.get("*", (req, res) => {
res.sendFile(
path.resolve(__dirname, "../", "client", "build", "index.html")
);
});
}
// Use default router
server.use(router);
server.listen(PORT, () => {
console.log(`JSON Server is listening on port ${PORT}`);
});
I expected the request to go thru and load up some data from api/db.json, with a resquest url of https://streamy-app.herokuapp.com/streams but instead i got a request url of http://localhost:4000/streams, which of course leads to the CORS issue below
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:4000/streams. (Reason: CORS request did not succeed).
I would truly appreciate any suggestions, been working on this for days.
Alright looks like I figured it out. I simply went into streams/client/package.json and added
"proxy":"http://localhost:4000"
I then went into streams\client\src and deleted the api folder which contained my custom axios with a base url. using instead axios out of the box for my action creators
const response = await axios.get("/streams");
dispatch({ type: FETCH_STREAMS, payload: response.data });
};
Now while running locally in development mode, I'm able to make a request to http://localhost:4000/streams, but after deploying my node app to Heroku I successfully make a request over to https://streamy-app.herokuapp.com/streams
hope this helps someone with slimier issues.
First, you should know that Heroku doesn't allow to expose multiple ports, which means you should change the approach of multiple ports to something else (see this answer).
Second, the file client/src/apis/streams.js is hard-coded configured to send requests to http://localhost:4000/ - which is not a good idea.
Whatever approach you choose - even deploying to another host server - you will need to dynamically configure the API endpoint, per environment.
I would also recommend you to:
Change the way you deploy react, as explained here.
After doing the above, consider consolidating your API service with the static server, so that you don't need multiple ports, and then everything becomes easier.

How to emulate traffic in express.js

I have a node express server responding to http traffic:
const http = require("http");
const express = require("express");
const app = express();
const server = http.createServer(app);
app.use(function(req,res,next){
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
and all that works fine. I'd like to have a program on my node server inject emulated http traffic into the express stack, without a network connection. I can't just magic up a (req,res) pair and call a middleware function like the one in app.use above, because I don't have a next to give it, and my req and res will not be the ones next passes on to the next middleware in the stack.
Edit: What I actually have is a websocket connection sending data packets of a different format, different data contents from http traffic that can also carry the same information. I can take those websocket packets and build from those a request that is in the same format that the http traffic uses. I would like to pass that transformed request through the express http middleware stack and have it processed in the same way. Going all the way back to create an http request having just dealt with a ws request seems a bit far.
What's the simplest way to emulate some traffic, please? Can I call a function on app? Call some express middleware, or write a middleware of my own to inject traffic? Call a function on server?
Thanks!
Emulation traffic by calling some Express.js internal functions isn't the right way. Much easier is to trigger the server by HTTP request from the same process
const http = require('http');
const util = require('util');
const express = require('express');
const app = express();
const server = http.createServer(app);
app.use(function(req, res, next) {
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
const port = 8081;
server.listen(port);
http.request({ port }).end();
From your question
I'd like to have a program on my node server inject emulated http traffic into the express stack, without a network connection
Can you clarify, why without a network connection?
A few things:
You need to make an endpoint
You need to host your server somewhere
You need something to send requests to your server
Express provides you a way to receive requests (req, res) (might be from a browser, might not be), perform some operations, and return responses (req, res) to the requester.
The expression
app.use(function(req,res,next){
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
is actually a middleware function. This will take every request to your server and change the request object created by express into a string, and print it in your server log.
If you want a testable endpoint, you would add this to the bottom of the snippet you posted
app.get('/test', function (req, res) {
res.json({success:true})
})
This tells your app to allow GET requests at the endpoint /test
Next you're going to need to host your express server somewhere you can send requests to it. Your local machine (localhost) is a good place to do that. That way, you don't need an internet connection.
Pick a port you want to host the server on, and then it will be reachable at http://localhost:<Your Port>.
Something like this will host a server on http://localhost:3000. Add this below the route we declared above:
server.listen(3000, function() {
console.log('Server running on port 3000');
});
Finally, you'll need a way to send requests to the server on localhost. Postman is a great tool for testing express routes.
I would suggest installing Postman and using that to emulate http traffic.
Once your server is running, open postman and send a GET request to your server by entering the server address and port, and hitting the blue send button (You'll be sending the request to http://localhost:3000/test).
Here's an image of what postman should look like if all goes well
You should also see your middleware fire and print out the request object in your terminal.
Good Luck!

how can I make an endpoint on express that never responds

I want write a test in mocha for how a timeout is handled.
I can set up a server that will never answer using netcat nc -kl 8080 (thanks https://stackoverflow.com/a/37465639/5203563).
However, since I already run an express server for all my other test endpoints inside mocha, it would be great if I could achieve the same thing with an express endpoint.
Does anybody know if that is possible?
Just don't return a response
var app = require('express')();
app.get('/fail', function(req, res) {
// does nothing
});
app.listen(8080);
Don't return the response from the route.
app.get('/', function(req, res) {});

Resources