I am trying to use express and body-parser libraries to create a simple node server. It is not supporting the static files as I stated below in the example. What is the mistake which i am making? Kindly help me.
server.js
var express = require("express");
var bodyParser =require("body-parser");
var app = express();
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({extended:false}));
app.get('/',function(req,res)
{
res.sendfile("index.html");
});
app.listen(3000,function()
{
console.log("Server started on Port 3000");
});
Package.json
{
"name": "blog post",
"version": "0.0.1",
"description": "Package.josn for node server",
"repository": {
"type": "git",
"url": ""
},
"private": true,
"dependencies": {
"body-parser": "^1.14.1",
"express": "^4.13.3"
}
}
I have updated my server.js as per the recommendation.
server.js (updated)
var express = require("express");
var bodyParser =require("body-parser");
var app = express();
//Here we are configuring express to use body-parser as middle-ware.
//app.use(bodyParser.urlencoded({extended:false}));
app.use(express.static(__dirname + '/public'));
app.get('/',function(req,res)
{
res.sendfile("index.html");
});
app.listen(3000,function()
{
console.log("Server started on Port 3000");
});
Worked Version
server.js
var express = require("express");
var bodyParser =require("body-parser");
var app = express();
//Here we are configuring express to use body-parser as middle-ware.
//app.use(bodyParser.urlencoded({extended:false}));
app.use(express.static(__dirname + '/'));
app.get('/',function(req,res)
{
res.sendfile("index.html");
});
app.listen(3000,function()
{
console.log("Server started on Port 3000");
});
You will need to make files public before using them as static files from expressjs server as below -
app.use(express.static('public'));
This serves your public directory as static directory. Put all your static files in public directory and serve.
If you want to serve from multiple directories you can do following -
app.use(express.static('public'));
app.use(express.static('files'));
More info - http://expressjs.com/starter/static-files.html
The only route you show is this:
app.get('/',function(req,res)
That's for the URL: localhost:3000/.
But, the URL in your image is localhost:3000/about.html which you do not have a route for. So, you can either make a route for that particular URL or you can use express.static() to automatically serve files from a particular directory.
Express does not automatically serve ANY files (unlike some other web servers) so any file that you want served must have a route that handles it (either individually or a route that handles many files).
Related
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' })
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' })
I have created a simple Express JS app. and it is working fine in localhost. when I visit localhost:8000 I see static files (index.html, style.css and frontend.js).
I have tried to deploy that app in a server using cPanel. and I have installed Node app and dependencies using package.json successfully. But when I visit the domain I just see a message (Node JS app is working, Node version is 10.24.1).
How to make my app to point and display the static folder (index.html) and run the app?
My app architecture:
server.js
package.json
public/index.html
public/style.css
public/frontend.js
And here is my server.js startup file:
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Dependencies */
const bodyParser = require('body-parser');
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('public'));
// Setup Server
const port = 8000;
const server = app.listen(port, function(){
console.log(`server running on localhost: ${port}`);
});
//POST Route to store data in the app endpoint, projectData object
app.post('/addData', addData);
function addData (req, res){
let data = req.body;
projectData = data;
console.log(projectData);
}
app.get('/getData', getData);
function getData(req, res) {
res.send(projectData);
}
The problem here is that you are not pointing a route to send the HTML file. Otherwise the client would have to point it to the correct path of the file, Like localhost:3000/index.html.
you need to send it from the server using app.get
app.get("/", (req, res) => {
res.sendFile(__dirname + "path to the file");
});
The problem was that I have created the app in a subfolder of my domain.
But when I have created subdomain and reinstalled the app inside it, the app is pointing to static folder successfully.
I am following a tutorial (https://levelup.gitconnected.com/simple-application-with-angular-6-node-js-express-2873304fff0f) on creating an app with Angula CLI, Node.js and Express. I use a proxy to start the app, the file defining the proxy looks like this:
{
"/api/*": {
"target": "http://localhost:3000",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
The command I use to start the app is this one:
ng serve --proxy-config proxy.conf.json
The tutorial said that:
All requests made to /api/... from within our application will be forwarded to http://localhost:3000/api/...
To be honest, I don't really know how it is supposed to work, because when I launch the app, I still use the URL: http://localhost:4200/ .
But I didn't have a problem until now. I just created a route with Express.js at the Endpoint /api/v1/generate_uid .
But the problem is when I go to http://localhost:4200/api/v1/generate_uid it shows this message:
Error occured while trying to proxy to: localhost:4200/api/v1/generate_uid .
The following is the message I get in the console:
[HPM] Error occurred while trying to proxy request /api/v1/generate_uid from localhost:4200 to http://localhost:3000 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
And when I go to http://localhost:3000 it always says that the connection has failed.
For further references, Here are the app.js of my express API and generate_uid.js which defines the route:
app.js
var express = require('express');
var uid = require('uid-safe');
var router = express.Router();
router.get('/', function(req, res, next) {
var strUid = uid.sync(18);
res.json({guid: strUid});
});
module.exports = router;
generate_uid.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var users = require('./routes/users');
var generate_uid = require('./routes/generate_uid');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser())
app.use('/api/v1/users', users);
app.use('/api/v1/generate_uid', generate_uid);
module.exports = app;
So I really don't know what the solution is. Thanks in advance for your answers !!
As said in the comments, it looks like the app doesn't have the .listen() function, which is very important to bind to the port.
app.listen(3000, () => {
console.log("Server started in port 3000!");
});
I have a basic script source link:
// index.html
<script src="/js/jquery.js"></script>
Which doesn't work, despite the file existing. I tried to link to it in the Node.js server but it threw an error that express wasn't defined, yet it is.
//server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var clientlist = [];
app.get('/', function(req, res) {
res.sendfile('index.html');
app.use(express().static('/js/jquery.js'));
});
Your requires are wrong, and hence express is not defined
Chamnge your first line var app = require('express');
var express = require('express');
var app = express();
Here is my solution.
Note:
You may want to replace '/var/www/nodeserver', with the directory, you are working in!
First of all, don't use res.sendfile(), it is deprecated, use res.sendFile() instead.
Or just serve a complete directory:
Setting all up
index.js
This could be your 'index.js' in '/var/www/nodeserver':
// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
// Change 3000 to whatever port, you want to access the site with"http://127.0.0.1:3000"
var port = process.env.PORT || 3000;
server.listen(port, function() {
console.log("Server listening at port "+port);
});
// Routing
var dir = __dirname+'/public'; // Path of the index.js but one dir further (public)
app.use(express.static(dir)); // serve all files in '/var/www/nodeserver/public/'
package.json
And you would need to have a 'package.json', containing this:
{
"name": "nameofyourapplication",
"version": "versionofyourapplication",
"dependencies": {
"express": "^4.10.2",
"socket.io": "^1.3.7"
}
}
Installation
Then install the dependencies defined in the 'package.json', with this command: npm install, while in the directory '/var/www/nodeserver/'.
This will install all the dependencies, locally, so it will create a folder named 'node_modules', in '/var/www/nodeserver'.
Using it
Next you just need to put all the files you want to serve, into the 'public' folder in '/var/www/nodeserver' and run the 'index.js' with node index.js.
The Filetree
Your filetree should then look something like this:
nodeserver
node_modules
express
socket.io
public
js
jquery.js
index.js
package.json
That should do it!
Before your file name put __dirname,'index.html'.
New code will be res.sendfile(__dirname + 'index.html');
And also your first line is wrong it should be var express = require('express');