Express js routing is downloading file and not rendering it - node.js

I am trying to implement a router on the server side with node.js and express.js.
I want to serve a file statically, but I already got this to work for a index.html file I created. No problems there.
My setup has tons of fileName.csp files (i.e. they end in .csp). Anyways, when I try to access a .csp file in the browser (inside it is really just a .html page - but the server side language must have it as a .csp file extension) but when I try to access it, the browser (google chrome) downloads the .csp file instead of rendering it!
I could really use some help since I'm new to all of this.
the line of code that is allowing the download of the .csp file, the code that exposes the directory where the .csp files live, is
app.use('/static', express.static('D:/CACHESYS/CSP/cah/'));
below is pretty much the whole snippet of code
var http = require('http');
var express = require('express');
var app = express();
app.use('/static', express.static('D:/CACHESYS/CSP/cah/'));
app.listen(3000, function() {
console.log('listening on port 3000');
})
app.get('/home', function(request, response) {
response.end('going to /home');
})
app.get('/csp/cah/MARS.csp', function(request, response) {
response.end('Trying to navigate to /csp/cah/MARS.csp');
})
p.s. the actual file path that is being downloaded is
D:/CACHESYS/CSP/cah/fileName.csp
just to give some more context for the question.
any help is appreciated
thanks!

You need to tell express what content type a .csp file is. You can do this with the following line:
express.static.mime.define({
'text/html': ['csp']
});
Although, if the file is an HTML file, it should probably have the .html extension. Also, if you are simply serving static files it is good practice to use an HTTP server like nginx or Apache to do that, rather than Node.js.
The reason this works is express will set the header Content-Type: text/html. This tells the browser it is HTML and it should render it as such. By default if a browser comes across a content type it doesn't recognise, it simply downloads it.

Related

Https createServer, load cookie and load clients index.html

I am trying to setup a login system on a website.
In order to do that, I have to load http only cookies.
In order to load them, I have to send them back to the client via the response object in the createServer function when https starts up.
I have successfully done that via here:
setting up https cookie in nodejs
The problem is twofold.
The https server cookie only loads if I include the port number in the url.
How do I get it to load without including the port number?
When the server kicks in and loads the cookie, the static index.html that was always supposed to load on the client, doesn't load and instead all i get is what was written into the response object on the server. How do I get to load the cookie, and just load that static html file?
I have tried sending in the entire html file as a respnose from the server side. But I'm not sure about that, plus i get MIME type problems in the browser.
I am not sure for the first part but for 2nd one,
you have to properly mention about response data type in response header.
so your should be something like this one:
var app = express(); app.get('/test', function(req, res) { res.sendFile('views/test.html', {root:__dirname}) });
For your first part of the question "How do I get it to load without including the port number?" You can try creating virtual host e.g for localhost:3000 will be something.xyz.
And for your second part you need to serve index.html with render method as follow
server.get('/', function (req, res) {
res.render('index', { greeting: 'Welcome' });
});
Where index is you static file inside view directory.
I've created a small demo, that might get you on the right track:
https://github.com/bergur/simple-server-with-websocket
This example includes:
https web server
websocket server
logic to get the cookies
serving a temp.html file without express
example of javascript class
example of dependency injection in nodejs

How to create a node based server to serve REST API and also deploy the application.

I am new to nodeJS server area, need help in understanding how to work with REST API (using express) and deploy the angular application over a singe node server and same ports.
By deploying i want to understand if user hit below url http://localhost:8000/<page_name> then the specified page should open.
And is user hit below url using get or post request
http://localhost:8000/api/<api_name> then a json or a text will be returned.
How to run both the thing over a single node server.
Lets assume, you have all your static files in the /public folder of you app. Generally spoken, if you are using express.static, you should also get your index.html because this is handled by default for each directory.
In your case, as you are using Angular, the routing is handled from the client side (SPA). You should only have one single index.html after building your Angular app. All files from your dist folder should then be placed into your /public folder. Then you need to make sure, that initial file serving provides your index.html like so:
In this example static files are served first, then your API and if nothing is found, you are getting back you index file.
const express = require('express');
const app = express();
// serve static files
app.static(__dirname + '/public'));
// serve your API
app.get('/api/welcome', function (req, res) {
res.send('Welcome');
});
// fallback routing (server side handling)
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + ‘/public/index.html‘
});
app.listen(3000);
Next time please make sure, to give all necessary information in your question ;-)
With the help from Sebastian, so far I can find a solution but its not working when i am hitting URL for different pages.
const express = require('express');
const app = express();
app.use(express.static('public'))
Please provide your suggestions.

ExpressJS static file serve always serves the same file

I have a expressJs setup which looks like this:
// Imports...
const app: express.Application = express();
const port: number = 3001;
const listener = new StatementListenerAPI();
app.use('/listen', listener.getRouter());
app.use('/welcome', router);
if (fs.existsSync('./client')) {
// Running in prod environment with pre built client directory. Serve this.
app.use(express.static('./client'));
}
app.listen(port);
So I have some routers connected to the express app, and at the bottom I declare that the directory client should be served statically. This directory contains an index.html as well as lots of JS, CSS and PNG files. However, no matter which URL I try to access from the express server, it always shows the code of the index.html within the statically served directory. The references to the JS and CSS files used inside the index.html also just return the code of the index.html.
I am using ExpressJS 4.16.3
What am I doing wrong?
Edit: So technically it works if using __dirname + '/client' instead of ./client. What I am now getting is that, when making GET requests from e.g. Postman (therefore "hand-crafting" the HTTP requests), I am always getting the correct results. If I call the resources from within my web browser, it still always shows the website (resolves the index.html). However, now all resources like JS and CSS scripts are being resolved properly, so apperantly Chrome resolves those dependencies properly, I am just wondering why I am still getting the contents of index.html as result when requesting some of the assets or some of the express endpoints via Chrome. API calls via code are working fine, so its only why manual chrome requests show this weird behaviour, at this point I am only asking out of curiosity.
Answer to your original question:
The path supplied to express.static should be relative to the directory from where you launch your node process or an absolute path. To be safe construct an absolute path (ie from the current directory or file). For example:
app.use(express.static(__dirname + '/client'));
Regarding your followup question:
I assume this is because Chrome uses heavy caching and it thinks this folder should return the html file. You can try and reset all caches in Chrome, or just for the page.

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 while acess static files in node server

Hi i am developing small application using react create app with node in thatis application i want to acess static file in node i use like this
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, "/", 'build', 'index.html'));
});
but i am getting getting error
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
This is because you are serving the same file for every request - also for the scripts required by the original HTML page. The browser request script, it gets HTML and the parser fails on < of <doctype> or <html>.
You can see in the Network tab of your browser's developer console all of the requests that your browser is making - I can bet that you're requesting something like script.js and instead of JavaScript contents you get the HTML contents of your index.html file.
It seems that you're using Express. Use express.static to serve static files instead of res.sendFile()
Since it seems that you have every static file in build, use something like this:
const path = require('path');
const express = require('express');
const app = express();
const dir = path.join(__dirname, 'build');
app.use(express.static(dir));
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
This is the entire program that you need. Of course you can change the port number.
It will serve your index.html correctly but it will also serve all of the other assets like images, client-side scripts required with <script>, CSS files etc. plus also other HTML files if there are any.
If you don't want to use Express then see this answer for more options of serving files:
How to serve an image using nodejs

Can't load local files when using NodeJS server

I'm very new to NodeJS, and I'm currently playing around with it (and websockets), so this question might be a bit dumb. Anyway, I'm following a tutorial which has given me a simple app.js containing the following:
var fs = require('fs')
, http = require('http')
, socketio = require('socket.io');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
});
socketio.listen(server).on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
In my index.html I'm trying to load some js and css files, but I can't seem to load them. The files are inside a js folder which is in the same directory as my app.js and index.html, and I'm trying to load them like so:
<script src="/js/script.js"></script>
If I look at the response from the request in my browser, it's returning the content of index.html.
Again, sorry if this question is silly, but I'm stuck and have no clue where to look.
Thanks!
A web server in node.js does not serve ANY files by default (unlike some other web servers). So, if you want js files to be served, you have to define a web server route that will serve them. The code you show returns index.html for all incoming requests coming into that http server so, it should be no surpise that when a request comes in for /js/script.js, your web server sends out index.html.
A typical framework to use with node.js for web serving is Express and it has express.static() that can be used to define a route that will cover all your static files or all files in a particular directory. You could, of course, code your own static file handling or find some other module to do that also. The point is that you have to write or configure some code to serve your static resource files. That is not done for you automatically by the node.js http server.
you can specify to the server in which folder to look for what
for static files such as css, images you can use
public directory, you can provide your custom directory, but it's better to use public ,same goes for views
always require
const PATH = require('path')
app.use(express.static(PATH.join(__dirname, 'public')));
for template files such as .ejs, .html, .jade use
app.set('views', PATH.join(__dirname, 'views'));

Resources