NodeJS and express, ENOENT on view file - javascript

I've got a weird trouble with my nodeJS app since I refactored it.
The app starts well, API answers correctly but when I try to go to /, I get this error : Error: ENOENT, stat '/views/index.html' in my browser.
I now use this folder tree :
project
front
views
index.html
bower_components
app
node
server.js
And here is the content of my server.js file :
var express = require('express');
var app = express();
var morgan = require('morgan');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var server = require('http').Server(app);
var io = require('socket.io')(server);
var fs = require('fs');
var nconf = require('nconf');
app.use(express.static(__dirname + '/../front'));
app.use(express.static(__dirname + '/../node_modules'));
app.use(express.static(__dirname + '/../bower_components'));
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({'extended': 'true'}));
app.use(bodyParser.json());
app.use(bodyParser.json({type: 'application/vnd.api+json'}));
app.use(methodOverride());
server.listen(8081);
(...) // some code to define API routes
app.get('/', function (req, res) {
res.sendfile('/views/index.html');
});
I tried to comment app.use(express.static(__dirname + '/../front')); and to call the view using '/front/views/index.html' but the result is the same.

ENOENT means Error NO ENTry which ultimately means it's not able to find your file.
int ENOENT
No such file or directory. This is a "file doesn't exist"
error for ordinary files that are referenced in contexts where they
are expected to already exist.
Your server is attempting to send a file from the root directory of your machine (/views/index.html). You'll probably need to adjust this to fit your file structure.
app.get('/', function (req, res) {
res.sendfile(__dirname + '/../font/views/index.html');
});

I believe you missed to set your views folder.
app.set('views', 'MY_DIR_PATH');

As #Sean3z suggested, I tried to change my sendfile declaration and got another error (Forbidden, sendStream error).
Finally I managed to make it work by changing my static files definition :
app.use('/front', express.static(__dirname + '/../front'));
And by modifying the sendFile : res.sendfile('front/views/index.html');
Strangely, nodeJS understands (but not me :) ) and call the right file at the right place. I just need to correct my calls in the differents file to be ok.
Thanks for the answers.

Related

How to create HTML pages with images with NodeJS [duplicate]

I want to serve index.html and /media subdirectory as static files. The index file should be served both at /index.html and / URLs.
I have
web_server.use("/media", express.static(__dirname + '/media'));
web_server.use("/", express.static(__dirname));
but the second line apparently serves the entire __dirname, including all files in it (not just index.html and media), which I don't want.
I also tried
web_server.use("/", express.static(__dirname + '/index.html'));
but accessing the base URL / then leads to a request to web_server/index.html/index.html (double index.html component), which of course fails.
Any ideas?
By the way, I could find absolutely no documentation in Express on this topic (static() + its params)... frustrating. A doc link is also welcome.
If you have this setup
/app
/public/index.html
/media
Then this should get what you wanted
var express = require('express');
//var server = express.createServer();
// express.createServer() is deprecated.
var server = express(); // better instead
server.configure(function(){
server.use('/media', express.static(__dirname + '/media'));
server.use(express.static(__dirname + '/public'));
});
server.listen(3000);
The trick is leaving this line as last fallback
server.use(express.static(__dirname + '/public'));
As for documentation, since Express uses connect middleware, I found it easier to just look at the connect source code directly.
For example this line shows that index.html is supported
https://github.com/senchalabs/connect/blob/2.3.3/lib/middleware/static.js#L140
In the newest version of express the "createServer" is deprecated. This example works for me:
var express = require('express');
var app = express();
var path = require('path');
//app.use(express.static(__dirname)); // Current directory is root
app.use(express.static(path.join(__dirname, 'public'))); // "public" off of current is root
app.listen(80);
console.log('Listening on port 80');
express.static() expects the first parameter to be a path of a directory, not a filename. I would suggest creating another subdirectory to contain your index.html and use that.
Serving static files in Express documentation, or more detailed serve-static documentation, including the default behavior of serving index.html:
By default this module will send “index.html” files in response to a request on a directory. To disable this set false or to supply a new index pass a string or an array in preferred order.
res.sendFile & express.static both will work for this
var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(public, 'index.html'));
});
app.use('/', express.static(public));
app.listen(8080);
Where public is the folder in which the client side code is
As suggested by #ATOzTOA and clarified by #Vozzie, path.join takes the paths to join as arguments, the + passes a single argument to path.
const path = require('path');
const express = require('express');
const app = new express();
app.use(express.static('/media'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'media/page/', 'index.html'));
});
app.listen(4000, () => {
console.log('App listening on port 4000')
})
If you have a complicated folder structure, such as
- application
- assets
- images
- profile.jpg
- web
- server
- index.js
If you want to serve assets/images from index.js
app.use('/images', express.static(path.join(__dirname, '..', 'assets', 'images')))
To view from your browser
http://localhost:4000/images/profile.jpg
If you need more clarification comment, I'll elaborate.
use below inside your app.js
app.use(express.static('folderName'));
(folderName is folder which has files) - remember these assets are accessed direct through server path (i.e. http://localhost:3000/abc.png (where as abc.png is inside folderName folder)
npm install serve-index
var express = require('express')
var serveIndex = require('serve-index')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
var port = process.env.PORT || 3000;
/**for files */
app.use(serveStatic(path.join(__dirname, 'public')));
/**for directory */
app.use('/', express.static('public'), serveIndex('public', {'icons': true}))
// Listen
app.listen(port, function () {
console.log('listening on port:',+ port );
})
I would add something that is on the express docs, and it's sometimes misread in tutorials or others.
app.use(mountpoint, middleware)
mountpoint is a virtual path, it is not in the filesystem (even if it actually exists). The mountpoint for the middleware is the app.js folder.
Now
app.use('/static', express.static('public')`
will send files with path /static/hell/meow/a.js to /public/hell/meow/a.js
This is the error in my case when I provide links to HTML files.
before:
<link rel="stylesheet" href="/public/style.css">
After:
<link rel="stylesheet" href="/style.css">
I just removed the static directory path from the link and the error is gone. This solves my error one thing more don't forget to put this line where you are creating the server.
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public')));
You can achieve this by just passing the second parameter express.static() method to specify index files in the folder
const express = require('express');
const app = new express();
app.use(express.static('/media'), { index: 'whatever.html' })

Why GET method make a request for css file [duplicate]

I want to serve index.html and /media subdirectory as static files. The index file should be served both at /index.html and / URLs.
I have
web_server.use("/media", express.static(__dirname + '/media'));
web_server.use("/", express.static(__dirname));
but the second line apparently serves the entire __dirname, including all files in it (not just index.html and media), which I don't want.
I also tried
web_server.use("/", express.static(__dirname + '/index.html'));
but accessing the base URL / then leads to a request to web_server/index.html/index.html (double index.html component), which of course fails.
Any ideas?
By the way, I could find absolutely no documentation in Express on this topic (static() + its params)... frustrating. A doc link is also welcome.
If you have this setup
/app
/public/index.html
/media
Then this should get what you wanted
var express = require('express');
//var server = express.createServer();
// express.createServer() is deprecated.
var server = express(); // better instead
server.configure(function(){
server.use('/media', express.static(__dirname + '/media'));
server.use(express.static(__dirname + '/public'));
});
server.listen(3000);
The trick is leaving this line as last fallback
server.use(express.static(__dirname + '/public'));
As for documentation, since Express uses connect middleware, I found it easier to just look at the connect source code directly.
For example this line shows that index.html is supported
https://github.com/senchalabs/connect/blob/2.3.3/lib/middleware/static.js#L140
In the newest version of express the "createServer" is deprecated. This example works for me:
var express = require('express');
var app = express();
var path = require('path');
//app.use(express.static(__dirname)); // Current directory is root
app.use(express.static(path.join(__dirname, 'public'))); // "public" off of current is root
app.listen(80);
console.log('Listening on port 80');
express.static() expects the first parameter to be a path of a directory, not a filename. I would suggest creating another subdirectory to contain your index.html and use that.
Serving static files in Express documentation, or more detailed serve-static documentation, including the default behavior of serving index.html:
By default this module will send “index.html” files in response to a request on a directory. To disable this set false or to supply a new index pass a string or an array in preferred order.
res.sendFile & express.static both will work for this
var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(public, 'index.html'));
});
app.use('/', express.static(public));
app.listen(8080);
Where public is the folder in which the client side code is
As suggested by #ATOzTOA and clarified by #Vozzie, path.join takes the paths to join as arguments, the + passes a single argument to path.
const path = require('path');
const express = require('express');
const app = new express();
app.use(express.static('/media'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'media/page/', 'index.html'));
});
app.listen(4000, () => {
console.log('App listening on port 4000')
})
If you have a complicated folder structure, such as
- application
- assets
- images
- profile.jpg
- web
- server
- index.js
If you want to serve assets/images from index.js
app.use('/images', express.static(path.join(__dirname, '..', 'assets', 'images')))
To view from your browser
http://localhost:4000/images/profile.jpg
If you need more clarification comment, I'll elaborate.
use below inside your app.js
app.use(express.static('folderName'));
(folderName is folder which has files) - remember these assets are accessed direct through server path (i.e. http://localhost:3000/abc.png (where as abc.png is inside folderName folder)
npm install serve-index
var express = require('express')
var serveIndex = require('serve-index')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
var port = process.env.PORT || 3000;
/**for files */
app.use(serveStatic(path.join(__dirname, 'public')));
/**for directory */
app.use('/', express.static('public'), serveIndex('public', {'icons': true}))
// Listen
app.listen(port, function () {
console.log('listening on port:',+ port );
})
I would add something that is on the express docs, and it's sometimes misread in tutorials or others.
app.use(mountpoint, middleware)
mountpoint is a virtual path, it is not in the filesystem (even if it actually exists). The mountpoint for the middleware is the app.js folder.
Now
app.use('/static', express.static('public')`
will send files with path /static/hell/meow/a.js to /public/hell/meow/a.js
This is the error in my case when I provide links to HTML files.
before:
<link rel="stylesheet" href="/public/style.css">
After:
<link rel="stylesheet" href="/style.css">
I just removed the static directory path from the link and the error is gone. This solves my error one thing more don't forget to put this line where you are creating the server.
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public')));
You can achieve this by just passing the second parameter express.static() method to specify index files in the folder
const express = require('express');
const app = new express();
app.use(express.static('/media'), { index: 'whatever.html' })

node server.js - Cannot GET /

I am currently working on a project which is a webpage using angular to dynamically change DOM elements. Within the project is a public folder which contains all HTML, CSS, JavaScript and JSON objects. The project must be distributed so I am using node to run from localhost. This is my server.js code:
var express = require('express');
var app = express();
var path = require('path');
app.get('/', function(req,res){
res.sendFile(path.join(__dirname + '/public'));
});
app.listen(8080, function(){
console.log((new Date()) + " Server is listening on port 8080");
});
When I head to localhost:8080 it just says Cannot GET /. Where am I going wrong?
The correct way to serve static files with express is as follows:
//Look for statics first
app.use(express.static(path.join(__dirname, 'public')));
//Return the index for any other GET request
app.get('/*', function (req, res) {
res.sendFile('index.html', {root: path.join(__dirname, 'public')});
});
Edit: on a side note this may be worthwhile to mention that app.get should be the last route declared in node so if you want API endpoints exposed declare them above (before) the final app.get.
You forgot to point to the actual html file you want to display. If you have a index.html in your public directory, just point tot '/public/index.html' . That works (tested it here).
Followed user Muli's answer and all files are now being served correctly. Code here:
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req,res){
res.sendFile('index.html', {root: path.join(__dirname, './public')})
});
app.listen(8080, function(){
console.log((new Date()) + " Server is listening on port 8080");
});

Node JS - HTML Paths

I recently have the problem that I dont get how the paths for html in node js work. I link my index.html's scripts as normal - relative to the index.html's file (node.js file and index.html are in the same directory "res.sendFile(__dirname + '/index.html');"). But if I open it up in the Browser executed with node js it just stats "cant GET blabla" for the scripts. Instead opening it up by just clicking index.html without node js those paths work! How do I have to write html paths for node js?
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
port = Number(process.env.PORT || 3000),
server.listen(port);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
Thanks for your time! :)
Look at this:
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
You have told Node "When the browser asks for / give it index.html".
What happens when the browser asks for someScript.js?
You haven't told Node what to do then.
(You'll probably want to find a library for serving up static files rather than explicitly handling each one individually).
you should configure express to server static files, for example, put all the static files under a directory called 'public'
var express = require('express');
var app = express();
var path = require('path');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.listen(8080);
ExpressJS to Deliver HTML Files
Render HTML file in ExpressJS
You can use
app.use(express.static(path.join(__dirname, "folder-name")));
Usually i put all my static files in a separate folder named "assets"
The I set up a static route as shown below:enter code here
app.use('/assets', express.static('assets'));
When you write:
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
It will only serve index.html file, not the other js scripts and stylesheets which you have added in your html.
There are 2 ways to solve that:
For both of them, I would suggest to use 'path' module.
Solution 1:
var path = require('path')
app.get('/path/to/js/foo.js',function(req,res){
res.sendFile(path.resolve(__dirname,'/path/to/js/foo.js')
})
app.get('/path/to/css/bar.css',function(req,res){
res.sendFile(path.resolve(__dirname,'/path/to/css/bar.css'))
})
and so on for every .css and.js file you have added in your index.html.
Solution 2:
You can create a public dir in your project's root dir. Inside which all your img, css and js files will be there.
Next,
var path = require('path')
app.use(express.static('public'))
app.get('/',function(req,res){
res.sendFile(path.resolve(__dirname,'/index.html')
})

Nodejs on single page

I'm new on Nodejs.
I have to do a web app with node js, express, socket.io on an existing website.
I use JXcore on Parallels Plesk panel to execute node.
But when I run js file and I visit any page on the website it returns "Cannot GET ".
If I use express get() function:
var app = require('express')();
var http = require('http').Server(app);
var path = require('path');
app.get('/path/to/index.html', function(req, res){
res.sendfile( path.resolve(__dirname + '/index.html') );
});
http.listen(10500, function(){
console.log('listening on *:10500');
});
it works on /path/to/index.html but every other website page is blocked by the same error "Cannot GET ".
Is there a way to run node only on one page?
Thanks
What your code is doing is defining just one route /path/to/index.html and mapping that to your index.html file. If you want to serve files from a directory, static html/css/js/whatever files, you can use the static method express provides:
app.use("/", express.static(__dirname + '/myHtmlDirectory'));
Change the "myHtmlDirectory" to whatever directory you store your files in and make sure to change the includes to define express:
var express = require('express');
var app = express();
However, if you want all GET requests to point to one single file, index.html for example, you can use the following:
app.get('*', function (req, res) {
res.sendfile( path.resolve(__dirname + '/index.html') );
});

Categories