Proxy running node-react application - node.js

I just created a react-node-SQL app and I want it to run on Google Cloud (not firebase)
My React app runs on different port and my node app runs on different port.
I followed this article and added this line in my react-app package.json but I didn't worked out i.e href in button was still going to localhost:8081 but It didn't worked
I had my node running on port 8080, In package.json of my react app i added "proxy": "http://localhost:8080/" and in button when I did href="/api/status" it was going to localhost:8081 on which the react app was running
Now, Is it possible to run both node and react under the same project? or we need to create separate project for them.
[Update:] I am using webpack, In my webpack config file, I added this
devServer: {
proxy: {
'/': 'http://localhost:8080'
}
},
The problem with this, that even in my react app, on Startup (running on 8081) when it opens the webpage localhost:8081/ it throws an error saying cannot get the page
but if I do something like this
devServer: {
proxy: {
'/api': 'http://localhost:8080'
}
},
it opens the page homepage normally. Now my api and callback uRL after authentication aren't configured with have prefix as api.

Basically, when you do an ajax request from react app, like axios or fetch it will use the proxy: <..> for the backend url. But, href doesn't work with proxies. In that case you need to manually configure proxy using the setupProxy.js documented in the manual proxy page.
Check out this issue:
Same error here, it still routes to localhost:3000/api/auth/google, my
CRA version is 2.1.3 It seems http-proxy-middleware is the only
working way. I have to Configuring the Proxy Manually
From the react doc:
If the proxy option is not flexible enough for you, you can get direct
access to the Express app instance and hook up your own proxy
middleware.
You can use this feature in conjunction with the proxy property in
package.json, but it is recommended you consolidate all of your logic
into src/setupProxy.js.

Related

Is there any dynamic way of changing the proxy target in React JS (or any other Front-end JS), without restarting the application?

Is there any dynamic way of changing the proxy target in React JS, without restarting the application?
I have multiple node JS servers in the local intranet (which Uses Private IPs, with No concept of deploying using public IP).
And I have one GUI using React JS, which will handle/manage multiple node JS servers.
Using one proxy settings configuration in package.json serves only one NodeJS server, If I update package.json with the next target in proxy, I need to restart the app again.
Is there any way to handle this?
First of all, it seems to be a bad idea to do so. You should have a stable / static proxy. Changing the proxy dynamically will cause many issues in your application.
you will have to handle n/w issues
you will have to handle white-listing/black-listing issues
assets loading issues and many other.
Still, if you want to try:
https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually
Check this URL.
This code worked for React 16.8.13
delete "proxy": {***} from package.json file
type npm install http-proxy-middleware
create the file src/setupProxy.js
-insert the code as following:
src/setupProxy.js
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = (app) => {
app.use(
createProxyMiddleware('/endpoint/*', {
target: 'http://address/',
secure: false,
}),
);
};
src/proxy-config.properties
end.point='/endpoint/*'
target='http://address/'
secure=false
And then, you need to change the above code to get the current proxy from a file / DB as follows.
With some code, check whether the proxy is working or not
If not, get new proxy from the file/DB
With you NODE code (or manually), keep changing the proxy-config.properties file.

node Vue.js different code scenario if run in dev mode

I have Vue.JS front app with nodeJS backend based on expressJS. ExpressJS also used as web server for statically built Vue.JS app
Front app communicates with express backend via rest and websocket. It uses url host from window.location instance and easily communicates with backend
In production mode, when built application in static expressJS server area, everything work perfect
In dev mode, Vue use it's own web server, and backend urls based on window.location are incorrect because no expresJS on same host and port.
So my question is it possible change some code blocks if running in dev mode ?
Like something this :
if( devmode)
{
const url = "http://somebackendhost/rest"
}
else {
const url = location.host ....
}
}
I will assume you are developing your Vue app using Vue CLI
Changing app behavior depending on environment
In Vue CLI you can use Environment Variables
if(process.env.NODE_ENV === "development")
{
}
This works thanks to Webpack's Define plugin and big advantage is that process.env.NODE_ENV is replaced at build time by the real value. So in production build Webpack will see just if("production" === "development") {} and happily removes the code in optimization phase because it knows this can never be true
Better solution
But I would not use this approach for your problem. Using different API server (not same as the server used for serving Vue SPA) can easily lead to CORS problems
Exactly for this use case, Vue CLI (and Webpack Dev server used under the hood) supports proxying
vue.config.js
module.exports = {
devServer: {
proxy: {
'^/api': {
target: 'http://localhost:58300/',
ws: true, // websockets
changeOrigin: true,
}
}
},
},
This config makes Vue Dev server to proxy any request to /api to other server running at http://localhost:58300/ (your node/express app) and change the origin (so browser thinks response came from the dev server)
All of this can be done without Vue CLI but you will need to set it up by yourself in Webpack config...
The problem
You can't access this information from your browser.
But there are three solutions:
Solution #1
On compilation time create a variable in code which defines devmode (const devmode = true;)
Solution #2
Because your bundler can minify your variable names or changing the scope for security reasons, may be the situation where you can't access it.
So second solution is to define devmode in your localStorage.
Solution #3
Third solution is almost the best.
If you are developing, you are probably accessing your web app via localhost.
location.hostname will return the name of host, so you can make something like:
const devmode = location.hotname == 'localhost';
Best solution
Do not do this. Develop a fully working web app using local REST API and define the URL of REST API in some variable, so when you are preparing your production app, you or compiler just changes the URL adress variable in code of your REST API.
Why is this the best solution?
Because it do not impacts your end-user's performance and they will be loading less code, which is the best practise.
Post Scriptum
Don't forget to remove all devmode codepaths when compiling production version!

Send axios (api) requests from react app deployed on heroku

In development, when i was running the react server on localhost:3000. I used proxy in package.json to set the baseurl for my backend server, which was running on loacalhost:5000. So i just edited proxy in package.json to "localhost:5000". So all the api requests sent from axios will be directed to that url.
axios.get("/name").then(res=>({...}))
A request identical to the above would be redirected to:
localhost:5000/name
In production, when i deployed the app on online platforms like heroku and vercel. The api requests sent from react-app through axios, all failed. When deploying on heroku/vercel, I changed the proxy to the online backend url.
I want to know how to change the proxy when a react app is deployed online (preferably on heroku/vercel). So that my api requests won't fail.
Tech stack: react for frontend, axios to send requests and firebase for the backend. The backend is also deployed on heroku.
Any kind of support would be appreciated. Even if there's a better platform to deploy the app, I can switch to that as well.
You should create a config object and pick base_url based on the env.
On local, it will pick development url and on Heroku it will use production.
const configs = {
development: {
SERVER_URI: 'localhost:5000',
},
production: {
SERVER_URI: 'HEROKU_URI',
},
};
module.exports.config = configs[process.env.NODE_ENV];
Also replace your axios calls like this:
axios.get(`${config.SERVER_URI}/name`).then(res=>({...}))

Shopify app with reactjs and nodejs without nextjs?

I am developing a shopify app so the reactjs handles the UI part and node-express handles the shopify auth things.
The tutorials in shopify site are
node, react and nextjs
node and express without reactjs
My concern is how to test the app without reactjs server side rendering with nextjs?
As we know node and react runs one seperate ports, so how can we handle the authentication flow with shopify?
How I am trying to work is
User enters app -> Node authenticates with shopify -> if auth success -> show react app.
Update : I am using ant design so ssr of ant design will be helpful.
Anyone please help me out with a solution.
After some research I got a simple solution and I am adding the links that give me solution.
React App is running in port 3000
Node server running in port 3001
Setup proxy in client package.json to localhost:3001
{
proxy: "localhost:3001"
}
Install http-proxy-middleware
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
Next, create src/setupProxy.js and place the following contents in it:
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/api', { target: 'http://localhost:3001/' }));
};`
6. That's all.
If using ngrok to make your localhost public, you may get Invalid Host Header error. Here is the solution.
ngrok http 8080 -host-header="localhost:8080"
ngrok http --host-header=rewrite 8080
https://stackoverflow.com/a/45494621/1445874
This 2 link gave me the solution.
When specified, "proxy" in package.json must be a string
https://create-react-app.dev/docs/proxying-api-requests-in-development#configuring-the-proxy-manually
It wouldn't be too difficult, you'd just have to set up Server Side Rendering with Express/Node in order to get react working. Next.js does this automatically saving you the time, but if you would like to do it yourself you can always.
You can follow this guide for reference - https://medium.com/bucharestjs/upgrading-a-create-react-app-project-to-a-ssr-code-splitting-setup-9da57df2040a
I'll do up my own example in a bit since I'm looking to do the exact same thing.

When to use proxy and when to use CORS in a react project?

I am a beginner at react development, I am confused about when I should use proxy or cors to make the front end talk to the back end.. Or do i need to use both? like proxy for development and cors for production?
CORS is completely related to back end when you want make your back end server accessible for any request use CORS.
example:
const app=require('express');
const cors=require('cors');
app.use(cors())// server will respond to any domain
Most of the time you are going to use a proxy when you want to be able to connect to an api that the webpack dev server isn't hosting but will be hosted by your server when published. An example will probably clear this up better than anything.
When developing you have the following scenario
API Server - running at localhost:4567 Webpack Dev Server - running at localhost:8080
Your App.js will make a request to the API server like so
$.ajax({
url: '/api/getOwnedGames',
...
});
Without a proxy this will actually make a request to localhost:8080/api/getOwnedGames (since you are browsing from the webpack dev server). If you however setup the proxy like so...
proxy: {
'/api/*': {
target: 'http://localhost:4567'
}
}
the api request will get rewritten to be http://localhost:4567/api/getOwnedGames.
if you aren't hosting your own api you probably don't need the proxy.

Resources