Referencing java script files from html in nodejs server - javascript

I am having a node js server that serves index.html when user hits localhost:3000/
app.get('/', function (req, res){
res.render('index.html');
});
However i cant figure out how i can refer to myscript.js javascript file from within the index.html.
<script src="script/my_script.js" type="text/javascript"></script>
I am calling a click button function from this file, but at run time this call gives 404. Please let me know how i can refer to a javascript file from within index.html in a nodejs server setup.

You can set up a static directory in which express will serve files as-is. For example:
app.use("/", express.static(__dirname + '/public'));
You can then create a "public" directory in your app root, and move your "script" folder inside. Any files (such as javascript, css) inside will be served directly to clients.
Docs

Related

node.js - How to send multiple images to a page on the server

How to send images to a page on my node.js server along with the html? How do I use express static to send images? (Need an example here)
Server side ->
app.get('/', function (req, res) {
res.sendFile(__dirname + '/login.html');
});
app.post('/m', function (req, res) {
res.sendFile(__dirname + '/m/a.png');
res.sendFile(__dirname + '/m/b.png');
res.sendFile(__dirname + '/m/c.png')
res.sendFile(__dirname + '/m/d.html');
});
In a web server, you don't just send multiple images to a page. Instead, the browser requests the page HTML, parses it, finds <img> tags in the HTML and then requests each of those images separately and your web server responds to each separate image request by sending the requested image.
If you put all your images in a common folder, then you can use express.static() to handle all the image requests with one line of code. For example a line of code like this:
app.use("/image", express.static(path.join(__dirname, "public")));
Would serve all image requests for URLs like this:
/image/a.png
/image/b.png
by finding the matching a.png and b.png in the "public" sub-directory below __dirname (which is the directory of the script). You can read more about express.static() here. You can obviously play with the path of the URL you want to use and the path where the images are found. The two just have to work together so that express.static() can find the right image in the corresponding place on the server hard drive where you've put it.
There is often some confusion in understanding how the separate path components in app.use() and express.static() work together. In the above example, the "/image" will be part of the request URL and this app.use("/image", ...) tells express that you want to apply this particular middleware to any request path that starts with /image.
Then path.join(__dirname, "public") is telling express.static() to take the rest of the URL path after the /image and look for that in the subfolder public below the directory __dirname. So, if the browser requests /image/a.png, the app.use() statement will trigger because /image matches that URL and then express.static() will try to find the remaining part of the path a.png in the directory you told it to look in.
On your server hard disk, this would look like this:
/myproject/
app.js
login.html
/public
a.png
b.png
I've shown login.html in the same directory as app.js only because that's how you're code seems to be currently written. I personally don't put any public files in the same directory as my server scripts because I want it to be easy to not make mistakes and accidentally expose my server files to the public.
I would more typically do it like this:
/myproject/
app.js
/public
login.html
a.png
b.png
app.use("/image", express.static(path.join(__dirname, "public")));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, "public", "login.html"));
});
Or, just let express.static() serve the login.html file too.

onload js call not working with node

I am starting to learn node.js, for now I am just trying to execute my old none node app with node. In this app, I have a html page with a body calling an onload js function. It's working just fine.
Now I have a a node app: app.js, simple as that:
var express = require ('express');
var app = express ();
app.use(express.static(__dirname + '/images'));
app.use(express.static(__dirname + '/CSS'));
app.use(express.static(__dirname + '/font'));
app.use(express.static(__dirname ));
app.use(express.static(__dirname +'/ketcher'));
app.use(express.static(__dirname +'/ChemAlive_JS'));
app.get('/', function(req, res) {
res.sendFile('/home/laetitia/Project/ChemAlive_Interface_Node/ChemAlive_Interface.html');
});
app.listen(8080);
And in the .html I still have:
<body onload="ketcher.init();">
but the function I want to load is not load at all anymore.
Any clue?
Thanks
You have not provided a lot of info in the question but from what you provide I can have few suggestions:
Suggestions
Instead of adding a lot of express.static uses:
app.use(express.static(__dirname + '/images'));
app.use(express.static(__dirname + '/CSS'));
app.use(express.static(__dirname + '/font'));
app.use(express.static(__dirname ));
app.use(express.static(__dirname +'/ketcher'));
app.use(express.static(__dirname +'/ChemAlive_JS'));
put those files (and directories) that you want to be served into one directory, e.g. called static, and use express.static once:
app.use(express.static(__dirname + '/static'));
or better yet, using the path module:
app.use(express.static(path.join(__dirname, 'static')));
you need to require the path module first with:
var path = require('path');
Now, instead of serving the single file for the '/' route with:
app.get('/', function(req, res) {
res.sendFile('/home/laetitia/Project/ChemAlive_Interface_Node/ChemAlive_Interface.html');
});
just put that file into the static directory as index.html so it will be served by the express.static middleware automatically.
Rationale
The way you have it configured currently, is that e.g. everyone can download your Node application - app.js with all of its configuration and even submodules etc.
Also, by using the express.static middleware many times I suspect that you are not sure how the files in those directories will be mapped to URLs.
Having a one place for static files makes it easy to verify whether any script tags have correct paths etc.
My guess
You don't provide enough info to be sure but my guess is that the JavaScript files for the main HTML file are not loaded correctly but you provide not enough info to be sure.
You can open the developer tools console in the browser and reload the page while the console is open and see for errors.
I suspect that the ketcher.init() method is being run but either the method, or the ketcher object is undefined, because some <script> tags failed to be loaded.
Example
The full example after following my suggestions would be much simpler:
var path = require('path');
var express = require ('express');
var app = express();
app.use(express.static(path.join(__dirname, 'static')));
app.listen(8080);
Maybe I would add some output to see what's going on:
var path = require('path');
var express = require ('express');
console.log('starting app.js');
var app = express();
app.use(express.static(path.join(__dirname, 'static')));
app.listen(8080, function () {
console.log('listening on http://localhost:8080/');
});
And now you will have all files that can be served to the browser in one place: in the static directory in this example.
Working app
You can see my example of a working Express application serving static files on GitHub:
https://github.com/rsp/node-express-static-example
In this example the directory for static files is called html but you can call it how you want, as long as it's consistent with how you use the express.static middleware.
You can start from this example project and just put your own files into the directory where express.static is told to look for files to serve.
You can also change the port number to match your needs.
More examples to do the same with and without Express, plus better explanation:
https://github.com/rsp/node-static-http-servers
More hints
The onload callback may not be fired if the page is waiting for some resources to load.
To see if your onload callback is firing you can change it to:
<body onload="alert('onload callback fired');">
Also the ketcher object may be not initialized or it may not have the init() method. After the page is loaded you can open the JavaScript Console and try running the method manually to see if it would work if it was fired:
ketcher.init();
You can also try commands like:
console.dir(ketcher.init);
console.dir(ketcher);
console.log(typeof ketcher.init);
console.log(typeof ketcher);
to see if the ketcher object contains what it should.
Even if the GET localhost:8080/ketcher.js gives a 200 OK status, it can still load some other resources that are not available or, as is very common with code that serve files with res.sendFile() (though unlikely in this case), it can serve HTML instead of JavaScript and result in a cryptic parse error on the < character - see this question for example:
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 while acess static files in node server
Other related answers:
How to serve an image using nodejs
Failed to load resource from same directory when redirecting Javascript
Sending whole folder content to client with express
Loading partials fails on the server JS
Node JS not serving the static image

Node is not finding js files included in html

I'm trying to build a simple chat app using node and socket.io. I am following the tutorial listed here: http://socket.io/get-started/chat/
My issues is that the tutorial has some javascript that is placed in a script tag directly in the html. I would like to move this code into it's own js file.
I made a file called chat.js, that is in the same directory as my index.html and index.js. In my html I put the following code in the header (I also tried right before the ending body tag too)
<script type="text/javascript" src="chat.js"></script>
However, when I run node index.js in terminal and go to localhost, I get a 400 for chat.js. I've tried placing "/chat.js" as well as "./chat.js" with no luck. All three files are in the same directory.
Any clues to what I am doing wrong will be appreciated.
My index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
node.js does not automatically serve any files like other web servers do. If you want it to send chat.js when the browser requests it, you will have to create a route for it in your node.js code so that the web server will send it.
If you use something like the Express framework, this can be done in perhaps one line of code with app.use(express.static(...)).
Notice how in the demo you linked to, there's a specific route for the / path. You need a similar route for /chat.js or you could use app.use(express.static(...)) to configure the automatic serving of a whole directory of files.
In the future, if you show your actual server code, then we could help more specifically with actual code that fits into your server.
Now that you've shown your code, you could add a specific route for /chat.js:
app.get('/chat.js', function(req, res){
res.sendFile(__dirname + '/chat.js');
});
Or, if you move chat.js to be in a public sub-directory under your app code, then you could serve all files in that directory automatically with this:
app.use(express.static('public'));
When Express gets a request for a route that doesn't have a specific handler, it will check the public sub-directory to see if a file matches the request name. If so, it will automatically serve that file.

How can I make script files available to the client in a Node.js Express app?

I'm building a Node.js Express app. When my client Html file tries to get a .js file from the server (when running <script src="somefolder/script.js"></script>), it can't access it. What's the common way to make script files accessible to the client in an Express app?
From the Express API:
Serve static content for the app from the "public" directory in the application directory:
app.use(express.static(__dirname + '/public'));
For example above assume that you will have the following "./public" folder structure:
/public
/javascripts
/custom.js
/stylesheets
/style.css
...
In this case to get script, or whatever you want you will need to write the following url: http://path_to_the_site/javascripts/custom.js.
Note that you don't need to write "public" before "javascripts".

Loading scripts in a Node app

This is my folder structure:
- getable_challenge
- node_modules
- stuff
- main.html
- main.js
- backend.js
- README.md
I want to load main.js from within main.html. Previously I had been accessing the page using the URL of file:///Users/adamzerner/code/getable_challenge/main.html, and a simple <script src="main.js"></script> allowed me to load the script.
But then I set up a Node server, at localhost:3000, and now it won't load the script. It's trying to load localhost:3000/main.js, which presumably is the wrong path. I'm not sure how to structure this... what should I do?
Server code (essentially)
var express = require('express');
var app = express();
app.listen(3000);
When you use the "file" protocol like that you aren't even using the web app to serve the script, you are directly accessing it on the local file system. That works fine when you are just running your app on your local machine but it completely breaks when you try to run it as a real app since the browser will have no idea where "file:///..." is, or even have permission to access it.
You need to put the client side scripts into a separate directory, usually named 'public', and then make your application aware of it. If you're using express you would do this:
app.use(express.static(__dirname + '/public'));
You want to put your statically served scripts ("public") into a separate directory so as to control access by your clients. If you just put them into the main directory and made the main directory accessible you could expose all your other files to public view, such as config files that sometimes contain passwords.
It also makes your structure much cleaner.
Try adding this line after var app
app.use(express.static(__dirname));
This should make your resources that are within your servers folder accessible. the var __dirname is the path to where your server is executed.

Categories