Is there anyway that I can get the running port? - javascript

I`d like to show in my React application the running port of the local server, is there any way to get it programmatically? The running port may defer if something is already running on the default port of create-react-app.

create-react-app is a React toolchain, which packages some useful tools together to let you dive into development without any initial setup. Local development server is a part of that toolchain, it's only purpose is to serve static files your react app needs.
Sure, create-react-app lets you configure some options with environment variables but it is not meant to serve as backend for your react application.
You can achieve this with your own backend by writing an endpoint to get the server port but for the local server I don't think it is possible.

This functionality is not available since React App and Local server are running independently.
However, your server port will be available when you start the server. So you can have another API that will simply fetch the port of the server and that can be displayed accordingly.
Something like this on the server.
app.get('/server/port', (req, res) => {
return res.json({port: server.address().port})
})
where your server is started at
const server = app.listen(20000)
In the react app, you can have the fetch request like this
fetch('http://localhost:20000/server/port')
.then(response => response.json())
.then(data => console.log(data));
// you will have the port no. in data.port
This will be helpful to you.

Related

Azure: Connect/Proxy Frontend (React) to Backend (Express/node.js)

I am currently trying to connect a frontend (React) to a backend (Express/nodejs) within Azure App Services. I am using Windows, since "Virtual applications and directories" are currently not available for Linux. However, according to my research, that is necessary in this case.
Backend sample: server.js
const express = require('express');
const app = express();
const port = 3003;
require("dotenv").config(); // For process.env
[...]
app.get("/api/getBooks", async (req, res) => {
const books = await Books.find();
res.send(books);
});
Frontend sample: App.js
const getBooks = () => {
axios.get('/api/getBooks')
.then(res => {
setBooks(res.data);
console.log("Got books: ")
console.log(res.data);
})
.catch(err => {
console.log(err);
})
}
Azure: Folder structure
site/server/server.js (Express)
site/wwwroot/index.html (React)
I successfully executed "npm install" via "Development Tools/Console".
The two are already connected via Virtual applications in Azure by using the following configuration.
Virtual applications
The app generally loads succesfully. However, the connection to the backend is not working.
How can I start the node.js server now on Azure and make the proxy working?
I tried to start the server via "node server" on the console. But this does not seem to be working.
I discovered two possible ways to solve this issue.
Assuming you have a client (client/App.js) and a server (server/server.js).
Serve the React App via node.js/Express
Based on the above architecture, a little bit of structure needs to be changed here. Because the React app is no longer output through its own server, but directly through Express.
In server/server.js, the following function must be called after express is declared.
app.use(express.static("../client/build"));
After defining some endpoints to the APIs, the last API node to define is the default route - the static output of the React build.
app.get("/", (res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
Using an FTP client, you can now create the /client/build directory that will contain the built React app. Of course, another directory structure can be used.
The client files from the built React app are then simply uploaded there.
The deployment from the server is best done via Visual Studio Code and the Azure plugin.
In the above structure, /server would then be deployed to your in the Azure extension (Azure/App Services --> Right click on "myapp" --> Deploy to Web App ...)
Create two App Services
For example: myapp.azurewebsites.net & myapp-api.azurewebsites.net
myapp must simply contain the built React app (/build) in the wwwroot directory. This can be achieved via FTP.
The deployment from the /server to *myapp-api is best done via Visual Studio Code and the Azure plugin.
In the above structure, /server would then be deployed to myapp-api in the Azure extension (Azure/App Services --> Right click on "myapp-api" --> Deploy to Web App ...)
Also worth mentioning is that CORS should be configured, so that API calls can only be made from myapp.azurewebsites.net. This can be configured in the Azure Portal.
Occasionally the node dependencies have to be installed afterwards via the SSH console in the Azure Portal. For me it sometimes worked automatically and sometimes not.
To do this, simply change to the wwwroot directory (of the /server) and execute the following command.
npm cache clean --force && npm install
Combine this with React Router
React Router is usually used with React. This can be easily combined with a static-served web app from Express.
https://create-react-app.dev/docs/deployment/#other-solutions
Excerpt
How to handle React Router with Node Express routing
https://dev.to/nburgess/creating-a-react-app-with-react-router-and-an-express-backend-33l3

NodeJs: How do I access the functions of my JavaScript backend from my HTML frontend?

Here is my HTML code in index.html.
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="stuff()">Click</button>
<script>
async function stuff() {
await connectToServer();
}
async function connectToServer() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
alert(this.responseText);
};
xhttp.open('GET', 'C:/Users/myName/myFolder/index.js', true);
xhttp.send();
return;
}
</script>
</body>
</html>
Then, here is my backend code in index.js.
const express = require('express');
const axios = require('axios');
const port = process.env.PORT || 8080;
const app = express();
app.get('/', (req, res) => {
res.sendFile('C:/Users/myName/myFolder/views/index.html');
});
app.listen(port, () => console.log(`Listening on port ${port}`));
I can type node index.js on the command line and run this program and go to http://localhost:8080/ . When I do this, the html page shows up as intended. However, when I click the button in order to make a GET request to the server side, I get a console error saying Not allowed to load local resource: file:///C:/Users/myName/myFolder/index.js . I'm using Google Chrome by the way.
I know that it is a security thing, and that you are supposed to make requests to files that are on a web server (they begin with http or https). I suppose then, my question is:
How do I make it so that my server file index.js can be viewed as being on a server so that I can call functions on the backend from my frontend?
You have to make an HTTP request to a URL provided by the server.
The only URL your server provides is http://localhost:8080/ (because you are running an HTTP server on localhost, have configured it to run on port 8080, and have app.get('/', ...) providing the only path.
If you want to support other URLs, then register them in a similar way and write a route to handle them.
The express documentation will probably be useful.
You should not need to load your server-side code into the browser. It's server-side code. It runs on the server. It isn't client-side code. It doesn't run in the browser. The browser does not need access to it.
If you want to load some actual client-side JS from the server, then use <script src="url/to/js"></script> (and not Ajax) and configure express' static middleware.
Let's improve your current flow by separating your backend API process from frontend hosting process. While backend can, it's not good in serving static html files (especially for local development purposes).
Run your backend as usual, node index.js. But as soon as this command will become more complicated, you will probably want to use npm scripts and do just npm start)
Run separate server process for frontend. Check out parcel, snowpack, DevServer. It can be as easy as npx parcel index.html, but this command is likely to change frequently with your understanding of your tool features.
To call backend, just add an API endpoint to an express app (just like you already did for serving static content), and call it, using backend process URL.
Usually, you will see your app on http://localhost/ and it should do requests to http://localhost:8080/.
If for some strange reason you will want to dynamically download js file from your server to execute it, you just need to serve this file from your frontend hosting process. In order to do so, different development servers have different techniques, but usually you just specify file extensions and paths you want to be available.
After editing frontend files, you will see hot-reload in browser. You can achieve the same for node process with various tools (start googling from nodemon)
If you find this way of operating not ideal, try to improve it, and check what people already did in this direction. For example, you can run two processes in parallel with concurrently.

How to point all node js microservices in single port locally and consume it in react app

In my React and node application, the is microservice architecture on the server side which is written in node.js, all the microservices are running different ports like
http://localhost:3001,
http://localhost:3002
so on..,
I want to point all the services in a single port so that I can consume that services in react through only one single URL as a base path.
want to do this on a local server/ local system.
As I want to run the application end to end on the local server.
Try to use an API GATEWAY with a Message Broker (rabbitmq for example) and in your service in index.js just consume the Queue of message broker. before send the response to the msg broker and This message are consume by your gateway
do you perhaps mean something like this?
you put this into the .env file
CONNECTION_URL = 'put your db url '
SECRET=...
BASE_URL='http://localhost:3000/'
NODE_ENV=env
as for front you can just call your functions by link
example
const getItem= () => {
Axios.get("http://localhost:5000/Items").then((response) => {
setListItem(response.data);
});
};
Using Nginx on WSL with Node.js resolved my issue, by creating a proxy server.

React-app frontend & express backend using nginx on ubuntu

I have been searching google for a couple of hours, been through multiple pages, and watching youtube videos but I am simply not able to find any guidance towards what to do in my case.
I have a react-app frontend running on Nginx.
With the frontend react-app I am running some Axios requests, example:
await axios.post("http://localhost:5000/api/getMessages", {});
I then have my express server receiving the requests and sending back responses, example:
app.post('/api/getMessages', (req, res) => {
Messages.find().sort('-createdAt').limit(10)
.then((result) => {
res.send(result)
})
})
Everything works fine in my local environment, but I am unsure of what to do when putting it on a live server with a domain using Nginx. I am able to get the react-app up and working just fine, but when making an axios request it simply returns net::ERR_CONNECTION_REFUSED
This is with my express server running in the back like a normal node project.
You must add rule for your server's ufw.
Ufw rule adding

is it possible to provide restful service from react?

i'm working on a web project that should provide restful post service with react framework.
there are a lot of consuming rest service example on internet.
however, i want to provide restful service.
I tried the following,
1- provide service from react framework. i see it is not possible.
2- provide service from express and binding it with react via proxy
https://www.youtube.com/watch?v=v0t42xBIYIs
for this example, get method works but post method does not.
my express server like below.
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/api/customers', (req, res) => {
res.json(req.body);
});
const port = 5000;
app.listen(port, () => `Server running on port ${port}`);
after that, , use proxy and react code like this
componentDidMount()
{
fetch('/api/customers')
.then(res => res.json())
.then(customers => this.setState({customers}, () => console.log('Customers fetched...', customers)));
at that point i get the below error
customers.js:18 GET http://localhost:3000/api/vehicles 500 (Internal Server Error)
thank you for all advice.
i'm searching for best practice.
The result of a React application build are script bundles and html files (also can include source maps for debugging) commonly referred to as build artifacts.
The best practice is simple:
When Express is involved the React app should download the build artifacts and API responses from Express (commonly called backend in this scenario).
What happens when this is not followed:
1. React frontend server (typically webpack-dev-server) is used in production. This is not a good idea, webpack-dev-serveris meant to be used in development only.
2. Browser detects that JS code from the bundles downloaded from one server (frontend) attempts to call another server (backend) and triggers a security violation which is meant to improve security. People then use CORS HTTP headers (sent by backend) to make the backend tell browsers: "Don't worry about security and don't trigger security violations, I (the backend) has been hardened to such an extent that I don't care that some code downloaded not from me tries to access me". The browser complies and this results in security needlessly watered down.
When to proxy:
In development only. The webpack-dev-server is excellent for development with its support for Live Reloading, HMR etc. To keep those advantages the backend (Express) can and should serve as a reverse proxy for the frontend. E.g. when Express receives a request for a build artifact, it should download it from the frontend first and then use it to send the response back. This ensures CORS issues do not arise.
Two issues stand out
Post vs Get
You're serving your api from a post endpoint. Change it to get.
app.get('/api/customers', (req, res) => {res.json(vehicleList);});
fetch
In the UI, it shows you are fetching from localhost:3000 when you should be fetching from localhost:5000. I assume your proxy is rerouting 3000 -> 5000 so hopefully this isn't an issue. I would however doublecheck and try hitting the localhost:3000/api/customers url (copy and paste that into the url bar) and see if you see your json.
Also
It is certainly possible to have express serve the static react bundle from a the same base url as your api.
e.g.
app.use('/', express.static('public'));
app.post('/api/customers', (req, res) => {
res.json(vehicleList);
});
Actually, I think you didn't focus that both are running on two different ports
like your server is running on Port:5000 and react project port:3000 so just add
"proxy":http://localhost:5000
//server.js (node file)***
app.get('/api/customers', (req, res) => {
const customers = [
{id: 1, Name: 'Rohan', email: 'r#gmail.com'},
{id: 2, Name: 'Rohan', email: 'r#gmail.com'}
];
res.json(customers);
});
const port = 5000;
app.listen(port, () => `Server running on port ${port}`)
// React Script***
class Customers extends Component {
constructor() {
super();
this.state = {
customers: []
};
}
componentDidMount() {
fetch('/api/customers')
.then(res => res.json())
.then(customers => this.setState({customers}, () => console.log('Customers fetched...', customers)));
}
i think there is no method for pushing data from server to client in a convensional way.
there is a good subject to push data from server to client. you may want to see that.
WebSocket vs ServerSentEvents

Categories

Resources