I am running a NodeJS server which uses a catchall route to serve a file 'index.html'. In that file, I am linking to a javascript file in the same directory. That javascript file is not being correctly loaded. The error in my console reads 'Uncaught SyntaxError: Unexpected Token <', which after researching seems to mean that the path to my JS file is incorrect. However, the js file is located in the same directory as 'index.html', and I am referencing it like so which should be correct?
Here is my code
server.js
var express = require('express');
var app = express();
var config = require('./config');
var apiRouter = express.Router();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var User = require('./app/models/User');
var jwt = require('jsonwebtoken');
var path = require('path');
//Set the public folder
app.use(express.static('/public'));
//Allows us to parse POST data.
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
mongoose.connect(config.db);
var apiRouter = require('./app/routes/api')(app, express);
app.use('/api', apiRouter);
//MEAN apps use a catchall after any routes created by Node.
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'public/app/views/index.html'));
});
app.listen(1337);
console.log('Server started at ' + Date());
public/app/views/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./test.js"></script>
<head>
<body>
<h1>Served by node + express.</h1>
</body>
</html>
public/app/views/test.js
console.log('test.js loaded');
You should set your static folder like this
app.use(express.static(__dirname + '/public'));
Also, your html file will look inside the /public folder itself for your script file. You'll need to give your index.html file the right path to your script file.
<script src="/app/views/test.js"></script>
Here's what's happening:
The browser requests /, which is responded to by your catchall route, so it gets back index.html.
The browser then sees a script in the html at ./test.js, so the browser then interprets that as /test.js and makes a request for that. The express.static middleware looks up public/test.js, which does not exist, so it passes execution to the next defined route that matches the request, which is your catchall route. This means html is sent for the javascript file, hence the error that you see.
So to fix this, you need to change ./test.js to the actual relative path (./app/views/test.js) or use an absolute path (/app/views/test.js) to make sure the correct path is always used, no matter what the current path is.
Additionally, you will need to change this:
app.use(express.static('/public'));
to something like this:
app.use(express.static(__dirname + '/public'));
Otherwise the express.static middleware will look for a directory named public off the root of your filesystem and you will have the same problem with the catchall route serving html for your javascript file request.
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 have this code
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
app.use(express.static(__dirname + '/uploads'));
console.log("listen to 8080");
server.listen(8080);
I have my image in /uploads/test.jpg but when I go to http://localhost:8080/uploads/test.jpg I get Cannot GET /uploads/test.jpg.
The static method indicates which root folder you will be serving your static content from. At the moment, your image will be accessible from http://localhost:8080/test.jpg.
To serve the images from a sub-folder, you would need to create this folder inside the static directory e.g.
app.use(express.static(__dirname + '/public'));
- public
-- uploads
---- test.jpg
app.use function has a default of '/' . When a route other than '/' is given , the middle-ware handle is useful only when the path segment is in the requests path name. For example if we mount a function in '/example' it would be invoked on /example and not at '/'. So your request is at "/uploads/test.jpg"
To do this
app.use('/uploads', express.static(__dirname + '/public'));
Now the middle ware is mounted at '/uploads' and services and any request made with path '/uploads' like GET /uploads/test.jpg etc.
Use the following code to serve images, CSS files, and JavaScript files in a directory named public.
var express = require('express');
var app = express();
app.use(express.static('public'));
Now, you can load the files that are in the public directory:
Examples:
localhost:3000/images/kitten.jpg
localhost:3000/css/style.css
localhost:3000/js/app.js
app.use('/static', express.static('./public'));
app.listen(2020, () => {
console.log("Server Started");
})
Run:
localhost:2020/static/test.jpg
I have some server side code in node js, which creates a express js object and runs the server. The app loads the index.html page which is inside the public folder. I have never written the code to serve the home page (mention below), still it works.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
I have not written this code so how does the index.html gets rendered. My understanding says express JS looks for the first instance of index.html page in all the static folders declared in the code and renders it, in my case the static folder is "publimc" and it has index.html at the root level.
server code follows below, which I have written.
var express = require('express');
var app = express();
var mongojs = require('mongojs');
var db = mongojs('contactlist', ['contactlist']);
var bodyParser = require('body-parser');
app.use(express.static(__dirname + '/publimc'));
app.use(bodyParser.json());
app.get('/contactlist', function (req, res) {
console.log('I received a GET request');
db.contactlist.find(function (err, docs) {
console.log(docs);
res.json(docs);
});
});
app.listen(8000);
console.log("Server running on port 8000");
The home page is rendered as part of the express.static middleware default options.
To disable this logic, set express.static(..., { index: false }).
If you want to change the file served as a home page, set express.static(..., { index: 'yourfile.html' }).
What this option does, in fact, is attempt to serve an index page with given file name for each directory in your public folder, so if you have public/foo/index.html then it will get served when requesting /foo/ path.
Folder structure
bin - www.js
lib - jsFiles...
models - jsFiles...
node_modules -Folders and Files
public - index.html
route - jsFiles...
index.js
package.json
I use Express, angular.js. Server starts at www.js and It calls
index.js. After that, When I type merely "localhost:3000" It shows me
public/index.html. I don't have route for '/' but It shows me
'public/index.html'. I can not understand this. Please let me know
about the process.
www.js
var debug = require('debug')('example-server');
var app = require(process.cwd()+'/index');
//listen at 3000 port
app.set('port',process.env.PORT || 3000);
var server = app.listen(app.get('port'),function()
{
debug('Express server listening on port ' + server.address().port);
});
index.js
var favicon = require('serve-favicon');
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//Connection for DB
require('./lib/connection');
var employees = require('./routes/employees');
var teams = require('./routes/teams');
var app = express();
// Writing at routing table
app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended:true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname,'public')));
app.use(employees);
app.use(teams);
// send 404 to errorhandler
app.use(function(err,req,res,next)
{
var err = new Error('Not Found');
err.status = 404;
console.log(error);
next(error);
});
...
...
module.exports = app;
In express.js the sequence in which you register your middleware makes a huge difference.
When express.js receives a request, it starts from top and executes registered middleware.
Middlewares are registered in express app using app.use(middleware_goes_here) this type of middleware gets executed no matter what the request url is on the other hand you can also register a middleware like app.use('/url/path',middleware_goes_here) in this case we are registering this middleware to '/url/path' so this middleware will only get executed when you visit '/url/path' (and non of the previous matching middleware serves the request without calling next() )
This app.use(express.static(path.join(__dirname,'public'))); line of code does the magic.
You can go here (express.static ref) to know more about static content serving and routing.
Basically what happens is, we are configuring express.static middleware to serve static content "as is" from "public" folder. So when you make any request and it matches a static content in public folder, then it will serve it otherwise express.static will call next middleware in sequence.
So in your case, the first middleware that actually server input request is express.static without any route filters, so it servers index.html even without a specifically defined route. If your public folder had file at public/javascript/jquery.js then following url will map to it http://localhost:3000/javascript/jquery.js
NOTE: You do not have to specify "public" in the url, the way in which express.static is registered, it will server contents FROM "public" folder.
................
UPDATE: How does default work in express.static?
By default, app.use(express.static(path.join(__dirname,'public'))); this will take index.html as default document. If you want to set index2.html as your default document, you can do that by doing something like this app.use(express.static(path.join(__dirname,'public'),{index: 'index2.html'}));
Hope it helps.
Put a relative path to folder(one up in hierarchy).
var app = require('../index');
This is driving me insane.
I have a node app with express. It serves up a file called index.ejs.
All I wanna do is import a javascript file on this page (something like jquery). But it won't pull it up, and I'm going nuts (as this should be simple).
On the server side I have this code in a file called app.js:
var express = require('express');
var app = express.createServer();
var hostName = (process.env.VCAP_APP_HOST || 'localhost');
app.listen( process.env.VCAP_APP_PORT || 8000);
app.use(express.static(__dirname + '/public/javascript/'));
//Create the view
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view options', { layout: false });
app.get('/', function(req, res){
res.render('index.ejs', {
item : "document.write('Hello World');"
});
});
In the ejs file, I have this:
<html>
<script>
<%= item %>
</script>
Link
<script type="text/javascript" src="/javascript/jquery.js"></script>
</html>
I can see in the console that the script is not loaded (it shows an error). But for the life of me I can't figure out why.
You need to add a static server to serve the other files you have under '/'. Currently your server is just responding to requests sent to '/' (and views).
Add this line to your express setup before app.get:
// DOCUMENT_ROOT should point to the directory that contains your javascript directory.
app.use(express.static(DOCUMENT_ROOT));
When your client asks for /javascript/jquery.js, your server is going to be looking for /public/javascript/javascript/jquery.js, and I rather doubt it will find it. Setting express.static()'s pathname to __dirname + '/public' should work, assuming that jquery.js is actually located in your_app/public/javascript.