How to use local static files while setting up Proxy server - node.js

I am setting up proxy server using NODE and EXPRESS. I have the same setup/codebase in local and proxy server. But i want to use all the js,css,images and other static content from local machine and json response from proxy server. Now since the proxy server also has same ,js,css,images, it is picking up everything from proxy. Do I need to restrict urls calls to not pick js,css,images and other static content from proxy but from local. How do i do that? Here is the code structure (both in local and proxy)
/src
/javacode
/WebContent
/js
/css
/images
/jsp
I want everything under /WebContent to be used from local.
This is how i setup proxy:
var proxy = httpProxy.createProxyServer();
app.route('/app/*$').all(function (req, res) { // proxy all requests
proxy.web(req, res, {target: 'http://proxy-server:7001'}); //sandbox
});

Given your file structure, you can use express.static to map your static /WebContent dir to a WebContent virtual path, like this:
var proxy = httpProxy.createProxyServer();
app.use('/app/js', express.static('WebContent/js'));
app.use('/app/css', express.static('WebContent/css'));
app.use('/app/etc', express.static('WebContent/etc'));
app.route('/app/*$').all(function (req, res) { // proxy all requests
proxy.web(req, res, {target: 'http://proxy-server:7001'}); //sandbox
});

Related

Proxy all requests to server in React using createProxyMiddleware

So on my dev env, I have a React Server on localhost:3000 and a NodeJs server on localhost:5000.
I have used createProxyMiddleware in React to configure the requests. Here is my config:
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function (app) {
app.use(createProxyMiddleware('/auth/google', {target: 'http://localhost:5000'}));
app.use(createProxyMiddleware('/auth/currentUser', {target: 'http://localhost:5000'}));
app.use(createProxyMiddleware('/api/*', {target: 'http://localhost:5000'}));
}
All of these routes work without any problems. For example I have a route like localhost:3000/api/list which gets routed to localhost:5000/api/list.
But now I have a route like localhost:3000/api/list/3132133ffdvf. The random string is some id. This above route does not get proxied. It gives me a 404.
Why is this happening? It shouldn't happen since I have created a proxy for /api/*. Can someone help me out?
The wildcard (*) only matches one directory level. This means that it matches /api/list but not /api/list/id, since the latter has two levels.
Either remove the wildcard, or use a globstar (**):
app.use(createProxyMiddleware('/api', {target: 'http://localhost:5000'}));
or
app.use(createProxyMiddleware('/api/**', {target: 'http://localhost:5000'}));

How to force express to always serve a fresh index.html?

So I have a create-react-app bootstrapped application that is being served by express. I've noticed that for some of my users their browser is caching the index.html and as a result my application is making requests for non-existent js and css assets.
To prevent this from happening, I've tried setting the cache control header on the express static server to be "no-cache"..which did not work. I've also tried forcing the ETAG to be false so the browser is forced to take back a new index.html, but this hasn't worked either.
This is how I am serving my application
app.get('/*', forceHttps)
// root (/) should always serve our server rendered page
// other static resources should be served as they are
const root = path.resolve(__dirname, '..', 'build')
app.use(
express.static(root, {
maxAge: '1d',
etag: false,
setHeaders: (res, requestedFilePath) => {
if (requestedFilePath.endsWith('.html')) {
res.setHeader('Cache-Control', 'no-cache')
}
},
})
)
app.get('/*', function(request, res, next) {
res.sendFile(path.join(__dirname, '..', 'build', 'index.html'))
})
Why do I run into this issue at all? After every build index.html changes and the ETAG should change because the index.html is different.
Why isn't my current solution working? I'm forcing there to be no cache
How do I solve this problem? I have existing users that have a stale index.html and I need to cache bust.
Thanks!

React & Express server not getting api requests in production /build

I have a React app running successfully locally and all api requests are successfully running from a separate server.
When I run a build, the path to the api server is lost and no data is loaded.
Below are a few screenshots...
Loading data successfully from api.
Pointing IIS to react /build folder using localhost:80. No data loading.
Here is an example of an api call in my node/express server/index.js file
app.get('/api/company', (req, res) => {
api_helper.GET('https://****/api/company')
.then(response => {
res.json(response)
})
.catch(error => {
res.send(error)
})
})
My package.json file has the url of the express proxy (running in the background).
"proxy": "http://localhost:5000/",
My question is, why isnt the api loading in production /build? I just get this...
Request URL: http://localhost/api/site
Request Method: GET
Status Code: 404 Not Found
Remote Address: [::1]:80
Referrer Policy: no-referrer-when-downgrade
but when just running locally (npm start) I get this and data loads from api.
Request URL: http://localhost:3000/api/site
Request Method: GET
Status Code: 304 Not Modified
Remote Address: 127.0.0.1:3000
Referrer Policy: no-referrer-when-downgrade
Any help appreciated, driving me mad! Thanks.
After much testing I discovered, you must put the routes before
Wrong Example:
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.use('/', routes);
Right Example:
app.use('/api', routes);
app.use(express.static(path.join(__dirname, 'build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
For anyone else struggling with this, I figured it out..
I had to add this to my express server.js file in the root folder of my project.
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
I then pointed to the address where express is running, in my case http://localhost:5000
This worked.
I also then set up a rewrite rule in IIS to point localhost and our domain name to localhost:5000
All working now, hope it helps someone else.
Thanks for your info. I am quite new to ReactJS and I also encountered similar problems when I created my production build. Actually I had added similar things like
app.use(express.static(<build_folder_dir>));
in my Express Server before then I came to search and see your post. Anyway, I did not add something like the second line of your code and my API calls are written in router created in a separate js file.
app.use('/api/some_path', <imported_router>);
In the exported router object, codes are written like this:
router.get('/some_sub-path')
To make API calls, I used axios in my react app
axios.get(
"/api/some_path"+"/sub-path?param_1="+<param_value>,
{
headers:{
"Content-Type":"application/json",
<some headers>
}
}
).then((res)=>{<Some codes using the res.data.<any param in body>>})
Finally,I added these lines in the server.js
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, <path of the index.html in the build dir>), function(err) {
if (err) {
res.status(500).send(err)
}
})
})
Yet, I made a stupid mistake that my app crashed because the app.get overwrite the settings in router. Just a reminder, if you enable any API calls in GET method, use regex to exclude the pattern for making API calls.

Node.js Express Error ERR_EMPTY_RESPONSE when using subdomain "www"

Im trying to use the following code as a reverse proxy. So when I set my pc'ed proxy settings to that, it would redirect Any url to the file.html. But when I type www. in-front of the domain I get error "ERR_EMPTY_RESPONSE" Without the subdomain "www" It works fine. Why is this? And how do I fix it?
expressApp.set('port', 6968);
expressApp.use(bodyParser.json());
expressApp.use(bodyParser.urlencoded({ extended: true }));
expressApp.get('/', function (req, res) {
res.sendFile('./file.html', {root: __dirname});
});
var server = expressApp.listen(6968);

How to manually serve files on Parse.com?

I've deployed a single-page app using a frontend framework to my Parse Hosting.
However, there's a huge issue in there: sub-paths get routed to the /public folder, and there's only an index.html and a bunch of assets in there.
I've tried numerous options on serving that static index file through all other routes, by using Express or HTTP in cloud/main.js, but it seems Parse runs a custom subset of Node modules. They've erased all filesystem methods. There's no sendFile() on Express API, no readFile()on fs module...
What can I do to achieve that?? I just need all paths not in the public folder to serve the same thing: my index.html file.
What I've already tried:
Read the file and serve it:
app.use(function(req, res) {
fs.readFile('../public/index.html', 'utf8' , function(err, data) {
if (err) {
console.error(err);
}
res.send(data);
});
});
Serve it as an Express Middleware (probably the most efficient way):
app.use(function(req, res) {
res.sendFile('../public/index.html');
});
Serve it as a catch-all route:
app.get('*', function(req, res) {
res.sendfile('../public/index.html');
});

Resources