I have an application mostly in Angular, and I want to hook it up to Express to encrypt and send private API keys so they won't be stored plainly on the client.
My problem is that the browser reads statically served js files as text/html, which is causing my javascript to not load. You can see that the response is 200 and the file is there, just not being interpreted correctly.
index.html has many script requests like these
<script type="text/javascript" src="/keys.js"></script>
<script type="text/javascript" src="/public/lib/underscore/underscore-min.js"></script>
<script type="text/javascript" src="/public/lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="/public/lib/bootstrap/dist/js/bootstrap.min.js"></script>
...
Express routing code:
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.resolve('./public')));
app.get('*', function(req,res) {
res.sendFile(path.resolve('./public/views/index.html'));
});
app.listen(3000);
Anyone experienced with express - what is the proper way to serve static files with different MIME types? I eventually need to serve text/css types as well.
You've configured your application to return index.html for every request:
app.get('*', function(req,res) {
res.sendFile(path.resolve('./public/views/index.html'));
});
So express dutifully does just that, serves index.html for any and all requests, including the requests that you want to have return the js files via your script tags. For example, a request to /public/lib/underscore/underscore-min.js will actually return the file at /public/views/index.html.
A simple fix would be to just return index.html for a root request:
app.get('/', function(req,res) {
res.sendFile(path.resolve('./public/views/index.html'));
});
In this way your index.html would be served at the root but your javascript assets could still be reached because you aren't serving index.html for every request.
Additionally, since you've told express that static assets can be found at /public, there's no need to include that directory when requesting them. So, your script includes should look like:
<script type="text/javascript" src="/lib/underscore/underscore-min.js"></script>
<script type="text/javascript" src="/lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="/lib/bootstrap/dist/js/bootstrap.min.js"></script>
I think this is your problem:
app.get('*', function(req,res) {
res.sendFile(path.resolve('./public/views/index.html'));
});
You're sending index.html for literally every request.
The actual problem is not that app.get('*', ...) resolves for all requests (and overwrites responses from other middlewares), but that express-static is used incorrectly here.
In your example express-static does not resolve the request to a valid static-file in that directory and just invokes the next middleware / handler, which is in your case the app.get('*', ...). And that's why you see your index.html for every request.
Solutions
- <script type="text/javascript" src="/public/lib/underscore/underscore-min.js"></script>
+ <script type="text/javascript" src="/lib/underscore/underscore-min.js"></script>
Either you specify your resources in the HTML without the prefix /public,
- app.use(express.static(path.resolve('./public')));
+ app.use('/public', express.static(path.resolve('./public')));
Or you adjust your express routing to handle the path prefix.
Related
How to serve file with static resources on all routes in Express JS?
I tried serving file with static resources using these line of codes,
app.use(Express.static(`${this.PATH}`));
app.use(Cors());
app.use(Express.json());
app.get('*', (req, res) => {
res.sendFile('./index.html',{root: path});
});
If the user visit route 'localhost/test', response is the index.html file. Then main.js is fetched also.
So this first part is working. However, if the user visit route 'localhost/test/testing', response is the index.html file but the main.js is not fetched correctly. The content of main.js is index.html that makes it result to "Uncaught SyntaxError: Unexpected token '<'"
It seems that the most likely possibility is that you need to change the <script> tag in index.html from this:
<script src="main.js"></script>
to this:
<script src="/main.js"></script>
When you enter /test/testing in the URL bar, the browser will request that file from your server. Your server will send back index.html. Then, the browser will parse that file and see the request from this tag:
<script src="main.js"></script>
Since there is no path on the file being requested, the browser will add the path of the current page to that file before it sends the request to the web server. That means, it will send a request for:
/test/testing/main.js
to your web server. But, your express.static() route won't find a file that matches that path. Therefore, it will fall through to your res.sendFile('./index.html',{root: path}); and the browser will get an HTML file when it's expecting a Javascript file and will thus give you the error you report.
I'm personally not a fan of catch all routes like you have that send index.html for anything that doesn't match something else because it can lead to very confusing bugs or problems, but if you do so, you HAVE to not use relative paths with any of your URLs in your page because they will all break when someone requests something like /test/testing.
I'm trying to send my 'index.html' file as a response to my local server and within that index.html, there is a link to an external CSS file.
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.get("/", function(req,res){
res.sendFile(__dirname+"/index.html");
});
and I've included the link in HTML head element like below:
<link href="styles.css" rel="stylesheet" >
Now the problem is that the 'styles.css' file is not loading up on the page. And on the Network section of the Chrome developer tools, it is showing status: canceled in front of the 'styles.css'.
Here is the screenshot of the canceled status showing for styles.css
Why is this happening and what is the solution to it? I've tried other people's solution of deleting the cache, but it doesn't work.
EDIT: Here, I have the exact same problem , and I've tried their solutions too, but it won't work
EDIT2: As I tried #wilkoklak's solution , It's still the same error
I just added the whole thing from the Bootstrap examples so don't really think that would be a problem
You have to serve the css file as well!
You can do this by using express.static
Create a folder named css and move your styles.css there
Your project structure would look similiar to this
project/
css/
styles.css
server.js
index.js
Then add this middleware:
app.use(express.static('css'))
This middleware will look for any match with files inside css folder, and send them in response.
When you GET / (when you open your webpage), the browser also sends GET /styles.css to your server. There was no route handler for /styles.css in your app. express.static does that for you
The problem of css not being loaded can be solved by using express.static and a dedicated static folder (Example: www) for static files.
Here is the working example using express.static:
Step 1: Put static files (index.html, styles.css in a static folder named www)
Folder structure:
/nodejs-web-demo
--> server.js
/www
--> index.html
--> styles.css
Step 2: Create the index.html and styls.css files in www (static) folder
File name: www/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/styles.css">
<title>Expressjs website</title>
</head>
<body>
<p class="my-style">Hello! How are you doing?</p>
</body>
</html>
File name: www/styles.css
.my-style{
color: blue;
}
Step 3: Use express.static to serve files from static folder
const http = require('http')
const express = require('express')
const path = require('path')
const app = express()
app.use(express.static("www"))
app.use('/', function(req,res) {
res.sendFile(path.join(__dirname + '/www/index.html'))
})
const server = http.createServer(app)
const port = 3000
server.listen(port)
console.log('Web server started on port # ' + port)
Output:
> node server.js
Web server started on port # 3000
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
My express app serves an HTML page from my disk upon the initial GET (i.e., if I hit "http://localhost:3000/" in the browser). Now I would like to access a JavaScript file which is in the same location in the disk as the HTML file. When I try to include it in 'index.html' by using
<script src="/myJavaScriptFile.js" type="text/javascript" ></script>
or
<script src="./myJavaScriptFile.js" type="text/javascript" ></script>
or
<script src="~/MyAbsolutePath/myJavaScriptFile.js" type="text/javascript"</script>
it doesn't work. The myJavaScriptFile.js file is never reached.
My express app looks like this:
var express = require('express')
var testMethod = require('./test')
var app = express()
app.use(bodyParser.urlencoded({ extended:false }));
var server = app.listen(3000, function () {
var host = server.address().address
var port = server.address().port
console.log('Example app listening at http://%s:%s', host, port)
})
app.get('/', function (req, res) {
console.log('In /');
res.sendFile(__dirname + '/index.html');
})
Express app is serving 'index.html' using the reference path '__dirname' + '/index.html' using res.sendFile function. (I am beginning to feel that this is a bad way of doing it. Please let me know if you think so too).
Also as we can see in the express app, an external JavaScript file called 'test' which is in the same location as 'index.html' and 'express.js' is being included without any issues. Could anyone please shed light on what's actually happening in the background? What exactly would be reference path for the JavaScript file that I can give in my 'index.html' if it is being served by express app? Thank you.
Serving files, such as images, CSS, JavaScript and other static files is accomplished with the help of a built-in middleware in Express - express.static.
Pass the name of the directory, which is to be marked as the location of static assets, to the express.static middleware to start serving the files directly. For example, if you keep your images, CSS, and JavaScript files in a directory named public, you can do this:
app.use(express.static('public'));
Now, you will be able to load the files under the public directory:
http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html
More Detail Here
Happy Helping!
I want to load local jquery file in my node js chat application.I have searched a lot but i cant find a proper solution.
<!doctype html>
<html>
<head>
<title>Socketio</title>
</head>
<body>
<!--This wont work -->
<script src="/socket.io/jquery.min.js"></script>
<!--This will work -->
<script src="/socket.io/socket.io.js"></script>
</body>
</html>
I just copy jquery.js file to socket.io folder.The socket.io.js file loads properly but jquery file didnt.Please help me
Here is my index.js file
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
server.listen(3000, function(){
console.log('listening on *:3000');
});
Finally I found the answer.I simply load the jquery file from localhost by this way http://localhost/assets/jquery.min.js.
app.use('/assets', express.static('assets'))
Put your jquery.min.js file in relative "/assets/jquery.min.js" path, then access as http://localhost/assets/jquery.min.js
"localhost" could be your ip address also.
Personally, I need this because I need a completely self contained demo to run independant of an available internet connection. Murphy's law is alive and well come conference time.
You might want allow Express framework to render HTML and pass in the static jQuery files. That's how I would do it.
This page explains how you can restructure your app to serve jquery files through the node routes instead of HTML code.
app.get('/jquery', function(res, req){
res.sendFile(__dirname + '/jquery.js');
});
This is what worked for me. (inside app.js)
const express = require('express');//path to express module
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
My file structure looked like this:
server.js
app.js
> public
index.html
> assets
> js
jquery.min
Then import jquery from index.html like normal:
<script src="assets/js/jquery-3.3.1.min.js"></script>
One workaround is to use the online source file link.
Try loading the jquery using the following,
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
That works fine at my end.