serveStatic() unable to locate a file - node.js

I am new to node.js, and I am trying to use the serveStatic function to locate a specific file.
When I specify the exact path in the argument it doesn't work. However it works only when I specify the directory only , and name the file index.html inside that directory.
Any idea on how I can use to it locate a specific file? Any help would be really appreciated from you guys thanks!
Below is my code
var connect = require('connect'),
http = require('http'),
serveStatic = require('serve-static');
var app = connect();
// app.use(serveStatic('public')); Works
app.use(serveStatic('public/test.html'));// doesn't work
app.use(function(req, res){
});
http.createServer(app).listen(3000);

serve-static is meant to serve a whole directory (with all sub-directories, if any). You can't use it to serve just one single file.
What you could do with serve-static is to set a default file to be sent when user requests a root of your directory (by default it's an index.html file):
app.use(serveStatic('public', {index: 'test.html'}));
But if you really want to send just a single file, then is's better to use this answer:
app.use(function(req, res) {
res.sendfile('test.html', {
root: __dirname + '/public/'
});
});
Though, the best possible solution is to read this file once and cache it. In this case there will be no need to access your storage device each time somebody is requesting this file:
var html_data = require('fs').readFileSync('./public/test.html');
app.use(function(req, res) {
res.send(html_data);
});

Related

Node.js + Express.js: How to use the root (/) for serving static files?

how do we serve a static file located in the root of the directory (/) and not in a folder of it?
I am using Node.js with Express.js, I have tried the following JavaScript code in my index.js file which is located in / (the root of the directory).
Attempt 1
const path = require('path');
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
})
Attempt 2
const path = require('path');
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, '/'));
})
Same output as Attempt 1
Attempt 3
app.use(express.static('/'));
Didn't work, showed an error: "Cannot GET /".
Attempt 4
app.use(express.static(''));
Didn't work, showed an error: "Path cannot be empty".
Please assist, I have refered to many other possible questions similar to this, and one of the questions didn't have an answer, so I am re-asking.
The argument you pass to express.static needs to be the path to the directory where the file is.
It shouldn't be / which is the root of the entire file system (you might intend it to be the URL path / and not the file system path / but that isn't what it means).
The special variables __dirname will give you the directory the JS file you are currently running is in. You probably want that (assuming a directory structure like this):
.../
|-server.js
|-index.html
So
app.use(express.static(__dirname));
Note that it is generally better to separate out your server-side code and the files you sent to the client. It makes it much easier to maintain the project in the long run and prevents your server side code (which might contain secrets) being exposed over HTTP by the static module.
There isnt any difference if you use / and no / in the script
for express use
app.use(express.static(process.cwd() + '/'));
try this it might be helpful
app.use(express.static('/'));
you do not need the "/" before "js" because it is already included above:
<script src="test.js"></script>

Heroku ENOENT: no such file or directory due to faulty express.js routing

I seen other people running into the same issue but I am starting to believe that I have a deeper issue with my express file setup since other solutions are not fixing it.
The idea that I had was to have a main page and then add folders for each of my projects. This is my folder structure:
And the code in the index.js is simply this:
const express = require('express');
const app = express();
app.listen(process.env.PORT || 5000, function () {
console.log('Example app listening on port 5000!')
})
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
app.use(express.static('asteroid'));
app.get('/asteroid', function(req, res){
res.sendFile(__dirname + '/asteroid/');
});
Now like many other question out there, the issue that I see in the log is "Error: ENOENT: no such file or directory, stat '/app/asteroid/index.html'". The app tries to go to /app and it can't find my files on there. I seem to be missing something simple.
Any idea what can be causing this in my case? I tried { root: __dirname }, joining everything with path(), and placed __dirname everywhere with no luck.
Looks like the file listing shows Asteroid uppercase. Maybe try renaming it to be lowercase everywhere?
If you're using express static then you don't need routes for each file. So maybe just use static or just use routes.

Why specify the path in app.use?

//app.js
var app = require('express')();
app.use('/test', require('./test'));
//test/index.js
var router = require('express').Router();
router.get('/test', function (req, res) {
res.status(200).send("success");
});
module.exports = routes;
Why does the path need to be specified in app.use and router.get? If I simply put app.use('/', require('./test')); instead, it seems to work just fine still.
If you change this:
app.use('/test', require('./test'));
to this:
app.use('/', require('./test'));
then you will have the same functionality as before of using the middleware exported by the ./test module on the routes that start with /test so you will experience that everything will work the same, but that middleware will also handle every other route not necessarily starting with /test which, depending on what it does and how it works, may or may not be what you want.
By using some path in the app.use() call you restrict the middleware that you're loading to that path only. When you use / then it's like saying "every path" because every path starts with the slash - even paths that are requested for URLs that doesn't include the slash are still requested with slash, using e.g. with HTTP/1.1 something like:
GET / HTTP/1.1
Host: localhost
With specifying router.get('/test', function (req, res) your handler method will handle any request thats ends in /test. Depends on where the router is use().
app.use(withPath, [callback...]
That mount your middleware functions tests at the speficied path /test
So your middlewares test will be execute when the base request url path match.

ENOENT: no such file or directory Heroku

I'm trying to display the content of a html file into node js file using readFileSync(). But I get this error :
Error: ENOENT, no such file or directory 'index.html'
at Object.fs.openSync (fs.js:427:18)
at Object.fs.readFileSync (fs.js:284:15)
at port (/app/web.js:6:22)
at callbacks (/app/node_modules/express/lib/router/index.js:161:37)
at param (/app/node_modules/express/lib/router/index.js:135:11)
at pass (/app/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/app/node_modules/express/lib/router/index.js:170:5)
at Object.router (/app/node_modules/express/lib/router/index.js:33:10)
at next (/app/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at Object.expressInit [as handle] (/app/node_modules/express/lib/middleware.js:30:5)
Here is my web.js file:
var express = require('express');
var app = express.createServer(express.logger());
var fs=require('fs');
app.get('/', function(request, response) {
// response.send('Hello World2 !');
response.send(fs.readFileSync('index.html').toString());
});
var port = process.env.PORT || 5000;
app.listen(port, function() {
console.log("Listening on " + port);
});
The "web.js" file and the "index.html" are in my github repository in the following address:
https://github.com/myUsername/bitstarter/blob/master/node-js-sample/web.js
https://github.com/myUsername/bitstarter/blob/master/node-js-sample/index.html
I tried different paths to address "index.html" none worked, such as
/bitstarter/blob/master/node-js-sample/index.html
/node-js-sample/index.html
/bitstarter/node-js-sample/index.html
./index.html
!
I'm using AWS EC2 ubuntun 12-4.
I've been straggling with this error for hours! Any help is highly appreciated.
The line that says app.get('/', ... means "when the client asks for '/'..." That is: it maps "web space" (URL paths) into actions. In your case -- read and return the contents of index.html.
So the proper request in your case is just www.mydomain.com/.
If you want to be able to serve static files, read up on express.static()
As Nitzan mentioned, in the long run you will want to learn how to use express.static() to serve html files and templates as you build out your node app. In response to your present question, however, I recommend the following:
Save the index.html file into the same directory as your web.js file in you EC2 instance (i.e. don't try to remotely access it on your github page).
Use the following code:
var content = fs.readFileSync('index.html', 'utf-8');
response.send(content);
This will read the contents of your index.html file into a variable called content while specifying the proper encoding. Then it will instruct node to send the content to the browser.
The problem appears to be that you are not adding "index.html" in git. Fist you need to add this to git and then push to heroku. This will solve your problem. Hope it helps :)

how to set path to the views (template) directory and to static files in node.js

I have created layout.jade, navigation.jade, and index.jade, and I want to glue them together.
In server.js, how do I
set the path to the views (template) directory, and
set the path to static files.
Is it required that node_module be placed in the folder that contains server.js?
Below is the code for server.js:
//create an app server
var express = require("express");
var server = express.createServer();
//set path to the views (template) directory
app.set('views', D:\#Programming\node.js\trial box\views);
//set path to static files
//how is the path to static files set?
app.use(express.static(__dirname + '/../public'));
//handle GET requests on /
app.get('/', function(req, res){
res.render('index.jade', {title: 'web project'});
});
//listen on localhost:3000
app.listen(3000);
Thank you in advance.
This questions a little old, but I'll still leave an answer. You'll need to place your app.use(... statement inside a callback function for app.configure() like so..
app.configure(function(){
app.use(express.static(__dirname + '/../public'));
});
You should use the express bin tool to bootstrap a project you'd get all that setup.
To install it:
sudo npm install express -g

Resources