I want to map all the requests that don't point to static files to my index.html and let javascript do the routing. But if I use the rules below all my requests (including the scripts and styles) hit the * rule.
const express = require("express");
var app = express();
app.get("*", function (request, response) {
response.sendFile(path.join(__dirname, "/index.html"));
});
app.use("/scripts/*", express.static("scripts"));
app.use("/styles/*", express.static("styles"));
app.use("/views/*", express.static("views"));
var port = process.env.PORT || 3000;
app.listen(port, function () {
console.log("Server is running, port: " + port);
});
I've also tried the reverse order.
Just to clarify here are some examples of what the expected behavior is:
/scripts/index.js => /scripts/index.js
/views/app.html => /views/app.html
/anything/here => /index.html
/ => /index.html
/a/lot/of/stuff => /index.html
I want to upload this to heroku and I don't want to use that many free credits. So I want to have all the routing and stuff on the JS to save up on computation on the server.
app.use('/scripts', express.static('scripts'));
app.use('/styles', express.static('styles'));
app.use('/views', express.static('views'));
app.get('/', function (request, response) {
response.sendFile(express.static(path.join(__dirname, 'index.html'));
});
Try to use the code in this manner and I really hope this will work for you
Try this code.
Put all your files inside public folder (including index.html and other folders like script, styles, views)
const express = require('express')
const path = require('path')
const app = express()
const PORT = process.env.PORT || 3000
app.use(express.static(path.join(__dirname, '/public')))
app.get('*', (req, res) => {
res.redirect('/')
})
app.listen(PORT, () => console.log(`Server is running, port: ${PORT}`)
Your code will start working if you shift app.use functions to the top of your code
Related
The idea is to make a lot of separate react apps on the one express server, so each of them should appear using the url something like mysite.com/app1, mysite.com/app2 etc
my express code:
const path = require('path');
const app = express();
app.use('/',express.static(path.join(__dirname, './public'))); // just a simple html, not a react
app.use('/app1',express.static(path.join(__dirname, './public/build-1'))); // react
app.use('/app2',express.static(path.join(__dirname, './public/build-2'))); // react
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.get('/app1/*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/build-1', 'index.html'));
});
app.get('/app2/*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/build-2', 'index.html'));
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`)
});
so, actually this works
but there's a problem - when visiting the root url of the site - mysite.com - I get the ordinary index.html file, not a react one, as expected, but using the path - mysite.com/app1 or mysite.com/app2 - the url changes to just mysite.com and the app1 or app2 launches from the root of the site, not staying on the route mysite.com/app1 or mysite.com/app2
and yep, I did configure the react's package.json file for both of the apps
{"homepage": "http://localhost:3000/app1"}
and
{"homepage": "http://localhost:3000/app2"}
the problem has been found: the route I configured in the React App rewrote the url path to the root, so that's why the bug occured
I am trying to upload my website on digital ocean using express, node and react. I can view my website on localhost:3000 but when I run nodemon on the publicip:3000 all I see is /root/website/src/index.html displayed on the page. Here is the server.js file
const express = require('express');
const app = express();
//Set port
const PORT = process.env.PORT || 3000;
//Import path
const path = require('path');
//Static files
app.use(express.static('build'));
//Server will use index.html
app.get('/*', (req, res) => {
res.send(path.join(__dirname + '/src/index.html'));
});
app.listen(PORT, () => {
console.log('Listening on port ${PORT}');
});
If you are using res.send() then it will send the path of the file. And path.join should contain the values separated with commas as it takes the values as string array.
Try this
If you want the actual file to send.
res.sendFile(path.join(__dirname ,"src/index.html"));
I'm creating routes in express.js using route parameters. I want a url example.com/case/firstCase with firstCase being a parameter.
However, I don't know how to use sendFile with params. What I'm trying to do is to append .html but I think it's not working since the method join add / between each element separated by comma. In other words, the path would be views/statics/case/firstCase/.html
Here is my code in server.js.
const express = require('express')
const app = express()
const path = require('path')
// no need to use app.use(app.router) because of that update
// function signature express.static(root, [options])
app.use(express.static('public'));
// mount root to views/statics
app.use('/', express.static('views/statics'));
const PORT = process.env.PORT || 3000;
app.listen(PORT,() => {
console.log(`Server is listening on port ${PORT}`)
});
app.get('/case',(req,res,next)=> {
res.sendFile('case.html', { root: path.join( __dirname, 'views/statics')})
})
app.get('/case/:case',(req, res)=>{
res.sendFile(path.join(__dirname, 'views/statics/case', req.params.case + '.html'));
}))
As above discussion your are not use view engine.
Add view engine like
Pug link
Ejs link
I've tried to write node server which would run React app created by create-react-app. Actually, something strange happens and I don't have any clue what I'm doing wrong (run app as node server/index.js):
export default (app, dirname) => {
app.use(favicon(path.join(dirname, '..','build', 'favicon.ico')));
app.use(express.static(path.join(dirname, '..','build')));
// initialize routers
bootRotes(app);
if (process.env.NODE_ENV === AVAILABLE_ENVIROMENTS.DEVELOPMENT) {
expressBootDev(app, dirname);
} else {
app.get('/*', (req, res) => {
res.sendFile(path.join(dirname, '..', 'build', 'index.html'));
});
}
}
build folder contains build react app which created the following command npm run build
Strange things are happening when after uploading index page it tries to upload static content. For example http://localhost:5000/static/js/2.30e86b6e.chunk.js. Browser just adds / after each static content url and it turns to http://localhost:5000/static/js/2.30e86b6e.chunk.js/ and of course this url doesn't match to express.static middleware.
Moreover, I've checked via Postman, that url GET http://localhost:5000/static/js/2.30e86b6e.chunk.js withot / at the end provides content which is expected.
I work with PRODUCTION env, it means that expressBootDev doesn't have any impacts.
Has anybody has the same issue? I've spent whole day and don't know hopw to fix it.
When I'm creating a simple code in a root app folder with almost the same logic and run as node server.js and it works as expected:
//server.js
const express = require('express');
const favicon = require('express-favicon');
const path = require('path');
const port = process.env.PORT || 8080;
const app = express();
app.use(favicon(__dirname + '/build/favicon.ico'));
app.use(express.static(__dirname));
app.use(express.static(path.join(__dirname, 'build')));
app.get('/ping', function (req, res) {
return res.send('pong');
});
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(port);
And I don't see any principal difference
var fs = require('fs');
var express = require('express');
var router = express.Router();
// GET: Sent some basic info for usage
router.get('/', (req, res, next) => {
var fname = __dirname + '/../public/index.html';
var val = fs.readFile( fname, 'utf8', ( err, data) => {
//send can only be called once, write can be called many times,
// in short res.send(msg) == res.write(msg);res.end();
res.writeHeader(200, {"Content-Type": "text/html"});
res.write(data);
res.end();
});
});
module.exports = router;
Here is the example how you can do a static file serving with node.
https://github.com/msatyan/ApiServe1/blob/master/routes/index.js
The full project is
https://github.com/msatyan/ApiServe1
FYI: Node.js with HTTP1 is not an efficient for static file serving by design, I believe HTTP2 support in node has addressed this problem. The reason for inefficiency with HTTP1 is that it has to take the file content read at native layer to JavaScript layer and then send it through HTTP server.
I am looking to capture all of the data from any request (images, fonts, css, js, etc) on my website so that I can capture the file details, specifically the file name and file size. I have found almost an identical question/solution:
Node.js : How to do something on all HTTP requests in Express?
But the solution appears to be deprecated with Express v4. Is there a simple solution to do this? As another approach I have tried the below solution with no luck:
var express = require("express");
var path = require("path");
var port = process.env.PORT || 3000;
var app = express();
var publicPath = path.resolve(__dirname, "public");
app.use(express.static(publicPath));
app.get("/", function(req, res){
// I want to listen to all requests coming from index.html
res.send("index.html");
});
app.all("*", function(){
// can't get requests
})
app.listen(port, function(){
console.log(`server listening on port ${port}`);
});
Also I am not looking to do this from Fiddler/Charles because I am looking to display this data on my site.
Express routes are predicated on order. Notice the answer that you linked in your question has the middleware defined, and used before all other routes.
Secondly you're trying to implement something that requires middleware, not a wildcard route. The pattern in link you provided in your question is not deprecated according to their docs.
app.use(function (req, res, next) {
// do something with the request
req.foo = 'testing'
next(); // MUST call this or the routes will not be hit
});
app.get('/', function(req, res){
if (req.foo === 'testing') {
console.log('works');
}
res.send("index.html");
});