I've scaffolded a full stack Mongo, Express, Angular, Node app using yeoman with the Angular Fullstack generator
It has created a server/app.js file, which executes a routes.js to handle resources being served by the express server.
The meat of routes.js looks like this:
// Insert routes below
app.use('/api/things', require('./api/thing'));
app.use('/api/users', require('./api/user'));
app.use('/auth', require('./auth'));
// All undefined asset or api routes should return a 404
app.route('/:url(api|auth|components|app|bower_components|assets)/*')
.get(errors[404]);
// All other routes should redirect to the index.html
app.route('/*')
.get(function(req, res) {
res.sendfile(app.get('appPath') + '/index.html');
});
My question is how any file other than index.html gets served to the browser. I've tested, and for example the file "http://localhost:9000/assets/images/yeoman.png" does get returned to the browser. But how? From what I am reading in the routes.js, a request to that png should return the text of index.html
I'm a bit confused by this and would really appreciate an explanation.
Thanks!
If you go into config/express.js you will see something like this:
app.use(express.static(path.join(config.root, 'public')));
Which should be self-explanatory.
UPD. With routes you can overwrite this behaviour for specific files (if you really need it).
Related
I have a node js and express server I run on localhost. Recently, while changing the server code from
app.get('/', (req, res) => {
res.sendFile(__dirname + '/public/index.html');
});
to
app.get('/', (req, res) => {
res.send('home');
});
The server still serves the "index.html" file and does not send the message "home". I also tried deleting all my "app.get()" and "app.post()" functions and it still runs as it was before the changes. I have double checked that I saved the file and restarted the server but even then, still does the same thing. The odd thing is that when changing anything else in the server code aside from my express code it runs as expected.
I tried searching my problem but no one is experiencing the same issues. Any help is appreciated, thanks.
All of your code is not listed, so this is an educated guess, but I would check to see if you are using express.static or another package to serve the directory your index.html file is in via app.use() before your routes. By default express.static will serve index.html if presented a root path ('/').
I was tasked with adding an additional layer of security by adding csrf token. I was able add the csurf package along with cookie parser but I am having issues with react and passing the token to react. I cant post my code here but maybe these specific lines listed below are enough to answer the question.
**//this line here is causing issues because if I remove the get route the index.html will still be servered regardless of whether or not I include the get route request!**
app.use(express.static(path.join(__dirname, 'build')));
//if i comment this get route out the react app is still being served
app.get('/', function(req, res) {
//added this console log to see if this was even being called and it is NOT being called
console.log('get request called');
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
Before I can even get to the csrf token I need to figure out why the get route is not being ran. Question: Why is the react application still being served even if i remove the get route? Is it something with the app.use(express.static...) line?
Yes express.static is serving the index file from your build folder.
https://expressjs.com/en/resources/middleware/serve-static.html
I'm using Express and create-react-app.
My React app is a ways along, and now I'm trying to serve it from an Express server.
// server/app.js
const express = require('express');
const path = require('path');
const app = express();
// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')));
// serve main file
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '..', 'build', 'index.html'));
});
module.exports = app;
(My build directory is populated when I do npm run build.
I view the page in Chrome, and what happens when loading the page at localhost:3000 is the Console prints Uncaught SyntaxError: Unexpected Token <, and in the Sources tab it shows that the content of my CSS and JS files are simply the same as index.html: as in this image.
This seems like a recognizable issue, so hopefully someone has seen this before. I'm sort of stumped on where to even begin, especially because I was actually serving the app from Express successfully at first. Then this started happening, then it stopped after some random switching of git branches and reverting and replaying changes, and then it started happening again. So I'm not even sure what makes it happen or not happen.
It appears that your app.use(express.static... call is failing, so instead all of the requests (including for the static assets) are being handled by the app.get('*', (req, res) => { part.
As you are intending to use this to serve a React app, I'd suggest taking inspiration from a boilerplate, "to see how it's done". I personally use NYTimes's kyt project and there's react-starter-kit too.
Try the following code changes which are detailed from the express documentation - serving static files in express:
Replace
app.use(express.static(path.resolve(__dirname, '..', 'build')));
With
app.use(express.static('build'))
Remove
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '..', 'build', 'index.html'));
});
The problem was "homepage": ... in package.json.
When npm run build runs and there is a homepage URL in package.json that has a non-empty path (like a Github Pages URL like this, https://username.github.io/project_name, where "/project_name" is the path), it changes where it expects the files inside /build to be. The requests for my js and css were going to /project_name/static/... instead of /static/....
It even said in the log output of npm run build:
The project was built assuming it is hosted at /project_name/.
You can control this with the homepage field in your package.json.
On my localhost, it wasn't hosted at /project_name/, so the paths were off.
I am building an app using node.js + express.js + react.js and I'm using webpack to compile the client side code. The problem I am having is after my client side code is compiled with webpack and I run my app, I cannot refresh the page.
My code:
My webpack compiles my files into /dist/index.html, my app runs on port 3000, and all client side routes are prefixed with /admin.
app.get('/', function(req, res) {
res.render('dist/index.html');
});
When I go to localhost:3000 in the browser and click around the links, the app works fine. However, if I go to, as an example, the about page:
localhost:3000/admin/about
And I refresh, I get the error Cannot GET /admin/about.
I believe the reason is my express router only knows about the / route... so If I refresh directly onto a route like /admin/about, express doesn't know what to render so my solution was to include a "catch all" route:
app.get('*', function(req, res) {
res.render('dist/index.html');
});
However, this keeps giving me the Error: Failed to lookup view "dist/index.html" error.
Can someone help?
Thanks in advance!
After research, I found the solution isn't res.render but res.sendFile:
res.sendFile(path.join(__dirname, '/dist/index.html'));
I'm using NodeJS, gulp and Angular with ui-router, and now when I configure angular to remove the tag (#) from the routes, I get the next problem, Angular's routes not works and navigator show this message:
Cannot GET /access
Can I limit nodeJs for so that it only responds to calls under certain route?
E.g: localhost:3000/api/*
Or i need to limit this performance with node and gulp ports.
The problem is that node.js is attempting to serve the routes.
You can fix this by creatg a catch-all handler that runs after your Node.js routes (i.e. your API calls, etc.).
Assuming you're using express, do something like this in your server.js file:
app = express();
app.use(app.router); // handles all your express routes
app.use(function(req, res) {
res.sendfile(__dirname + '/public/index.html'); // will execute angular code
});