A very simple question but bothers me a lot.
what's the difference between the following two cases ?
index.html
- script src="script/a.js"
- script src="/script/a.js" // starting with slash
and why my server can serve this request (starts with slash)
app.get('/script/a.js', function(req, res){ // with slash
res.sendfile(__dirname + '/realfolder/script/a.js');
});
no matter the url src on client side is any case of those two cases I just mentioned ?
On the other hand, I always got 404 error if I serve the request in the following way (starts without slash)
app.get('script/a.js', function(req, res){ // without slash
res.sendfile(__dirname + '/realfolder/script/a.js');
});
In my opinion, the path starts from '/' means the root folder of application and the other means relative path from __dirname. And I couldn't understand why my server can't handle app.get('script/a.js') this request which is without slash in the beginning ?
Anything wrong ?
When a path starts with a slash / it means that it is an absolute path.
When it doesn't start with a slash, it is a relative path.
Lets see an example. Imagine that my hard disk has only the following folders:
main
subfolder1
subfolder2
lastfolder
Now imagine we are in folder subfolder2 and we want to load a file that is inside lastfolder. We can load it with a relative path:
lastfolder/file.txt
But we can also use an absolute path:
/main/subfolder2/lastfolder/file.txt
Both paths are correct, but the relative one can fail if we move to a different folder (for example if we are in subfolder1), while the absolute path will always be correct (if we don't modify the folders of course).
Related
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>
I have a code line:
app.use(express.static('public'));
for static files in public folder, but build a route:
app.get('/search/jobs', jobs.index);
The Expressjs is putting /search before url.
And I'm a getting error in console browser:
GET: http://localhost:5000/search/css/materialize.css
Any idea?
You need to use absolute paths in your html/css (e.g. /css/materialize.css). With relative paths (e.g. css/materialize.css) the browser will look up the path relative to the current path/"directory" (/search in this case).
My app’s folder structure for NodeJitsu is as follows (i.e., when i do a jitsu deploy, I'm in the folder that contains "server.js" - i.e., the "server" folder).
Root server
|___server.js
|___package.json
client
|___www
|___index.html
|___css
|___js
|___etc.
So at the root is the folder "server", containing the starting script, “server.js”. Then there’s a folder called “client”, parallel to "server", with a folder within that called “www”, and within “www” is the main “index.html”.
In my “server.js” file, I have the following code:
app.get(‘/’, function(req,res)
{
var aPath = path.resolve(“../client/www/”, “index.html”);
res.sendFile(aPath);
});
I don’t have a app.use(express.static(__dirname + '/somefolder'). And when I start the app, I get this error:
Error: ENOENT, stat '/opt/run/snapshot/client/www/index.html'
My process.cwd() is /opt/run/snapshot/package. Obviously the above path isn’t pointing to the location where “index.html” resides. But I thought the way I do the path.resolve(…) should point to “index.html”. I can’t see where the problem is. If “server.js” is in the root, then to get to “index.html”, which is in “client/www/index.html”, then I should need to write “../client/www”, relative to the excuting script, to get to “index.html”, right?.
Do you have any insights as to where the path is not set up correctly? What should /opt/run/snapshot/ be pointing to? Or, what changes do I need to make in the get(‘/’) handler to correctly point to my “index.html”?
EDIT
I incorrectly drew the folder structure. Now it's correct.
I also turned off the app.get() and turned on the app.use(express.static(__dirname + '/../client/www/'). But to no avail: now i get a Cannot GET / error.
What I'm ultimately after is to have the "server.js" file be the Node server that, mostly, just serves AngularJS HTML files to the browser, with attendant images, stylesheets, etc., from the "client" folder. This is the server's main role, with an additional role of authenticating the app's users, employing the very nice Satellizer module. And that's it. I have a MongoDB attached, but otherwise this is a very common and straightforward Node.js server app.
Thanks!
Try it without rooting, resolving and log out to double check:
// notice no leading / which is root. __dirname should be the dir of current file running
var staticPath = path.resolve(__dirname, '../client/www');
console.log(staticPath);
Then pass that into express.static
app.use(express.static(staticPath);
I would probably recommend following the layout and convention of express generated apps with app in the root and static files under public
/public
<static files>
app.js
Then do what the generated app does:
app.use(express.static(path.join(__dirname, 'public')));
If I want to set up the directory .../whatever/stuff to be served statically, but referenced as http://example.com/mystuff, I tried doing this:
app.configure(function() {
app.use('/mystuff', _express.static(__dirname + "/whatever/stuff"));
app.use('/mystuff', _express.directory(__dirname + "/whatever/stuff"));
});
This mostly works, but if I reference a subdirectory of mystuff without a trailing slash, say http://example.com/mystuff/subdir, it redirects to the wrong place (http://example.com/subdir/), resulting in a 404. This is especially problematic with directory listings, since the directory middleware doesn't put a trailing slash on links to subdirectories.
Is there something I can do to get around this? (and is my syntax above correct?)
try this:
app.use('/mystuff*', ..);
I want a route called 'main' which will serve static files:
app.use('/main',express.static(__dirname+'/public'));
However when i do:
http://my.site.dev/main
The CSS and JS files won't download because it is trying to get them from
http://my.site.dev/css/styles.css
It should be getting the files from:
http://my.site.dev/main/css/styles.css
However, if I access my site with a trailing slash:
http://my.site.dev/main/
All files come through fine
Any ideas why not having a trailing slash messes up resources like CSS and JS from coming in?
This is an http problem, not just an Express-related challenge. The problem is discussed at:
Relative URLs and trailing slashes
http://www.bizcoder.com/the-mystery-of-the-trailing-slash-and-the-relative-url
If your URL is /main and your relative URL is css/style.css, it will resolve to /css/style.css; but if your URL is /main/, the relative URL resolves to /main/css/style.css.
My strategy for dealing with this is to redirect to add the trailing slash. Like this in Express:
app.all(/^\/main$/, function(req, res) { res.redirect('/main/'); });
app.use('/main/',express.static(__dirname+'/public'));
Or:
app.enable('strict routing');
app.all('/main', function(req, res) { res.redirect('/main/'); });
app.use('/main/',express.static(__dirname+'/public'));
How are the JS/CSS files requested in the HTML? If you're using strings like css/styles.css, then it will try to get them from the current directory. The directory for /main is / (just like /main.html would be), while the one for /main/ is /main/. A quick fix would be to use /main/css/styles.css in your HTML.