var path = require('path');
app.use(express.static("public"));
app.get('/', (req, res) => {
res.sendFile(path.join('/index.html'));
});
app.get('/contact', (req, res) => {
res.send('contact');
});
app.get('/contact', (req, res) => {
res.sendFile(path.join('/index.html'));
});
First get works fine and gets the page. Second get works and displays a string at a different url...but when I combine the two (page that previously displayed and address that previously displayed something) it says Error: ENOENT: no such file or directory, stat '/index.html' . Any clues why this isn't working?
Part 2: do I need to use path and public directory, or is there a simpler way to send files directly from the project folder like a simple node server does?
Related
Apologies for this question which may be seen as basic but I feel there must be an easy method for this for such a popular framework yet I am struggling to come across it.
I am wanting to serve page routes using a relative path.
i.e. sendFile("/pages/index.html")
but the only solution that works is using sendFile(__dirname + "/pages/index.html")
I have read posts which say to add app.use(express.static("public")) to serve static content but this only impacts get requests to the full URL from client not the sendFile() from server.
i.e. If client types http://...../pages/index.html it correctly returns but when they type http://...../ and I use sendFile("/pages/index.html") the route is incorrect.
Relevant chunks of code are below
const express = require('express');
const app = express();
app.use(express.urlencoded({extended: false}))
app.use(express.static("public"))
app.get("/", (req, res) => {
res.status(200);
res.sendFile("/pages/index.html")
});
Directory structure is public, public/css, public/js, public/pages.
Again all I'm trying to do is not have to write __dirname in every sendFile().
I feel like I'm missing something. Any suggestions are appreciated :) Thanks
As #Yasio linked https://stackoverflow.com/a/52031283/9488284 (Thank You).
The solution is to create a middleware function that prepends __dirname to every sendFile and then use that function instead of sendFile.
Like such
app.use((req, res, next) => {
res.show = (name) => {
res.sendFile(`/public/${name}`, {root: __dirname});
};
next();
});
You can then display pages (in my dir structure) using
app.get('/demo', (req, res) => {
res.show("pages/index.html");
});
i.e. when someone requests http://.../ you will return to them pages/index.html.
This essentially means instead of using sendFile() use show() to return files.
here I let you a question that is bothering me a little bit.
I have a middleware in my Express application that logs in a .txt file every path that I request. My code looks like this:
const fs = require('fs');
module.exports = function (req, res, next) {
fs.writeFileSync('log.txt', req.originalUrl + '\n');
next();
}
It works fine, but logs every resource from the request (the path of images, the path of css files, the path of js files) and I only want, the path present in the browser address bar.
Anyone knows how can I get that?
you need to chose wisely the position of your middleware.
to achieve what you say you need to put your own midleware after assets middleware
exemple
app.use(express.static('public'));
app.use(function (req, res, next) {
fs.writeFileSync('log.txt', req.originalUrl + '\n');
next();
})
app.get('/', () =>{
...
})
by doing this, your middleware will only be called if the path is not an asset.
my dir structure
/src
--/public
--/server.ts
--package.json
--package-lock.json
above is my director structure
app.use(express.static(__dirname + "/public/"));
// app.use(express.static("/public/"));
const path = require("path");
app.get("/", (req, res, next) => {
// res.sendFile(path.join(__dirname, + "public", 'index.html'));
res.sendFile(__dirname , "index.html");
//res.send('Testing one two');
});
const port = process.env.PORT || '5005';
app.listen(port, () => console.log("Server running on port 5005"));
when I run the above code, it works well on my local machine but won't work when it is deployed to Heroku,
I tried just passing a string like this and it worked, but when I want to render a static file like the HTML file it wont work on heroku, any help? i think the problem is my directory structure
app.get("/", (req, res, next) => {
res.send('Testing one two');
});
If I recall correctly, express.static middleware is separate from res.sendFile. In other words, even if you set express.static to public, it will not do anything to res.sendFile, as it takes the first parameter as a path.
In my humble opinion, it would be better if you were to use an absolute path, like the following snippet below.
const path = require('path');
/** Code here... **/
app.get("/", (req, res, next) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
Explanations:
path.join is an utility to join path segments into one path. It is cross-platform compatible.
__dirname will get the current directory that the script is running from.
Further reading: Express methods.
You just need to give the address of the index.html file in the path for the code mentioned below and paste this code at the end of the inside of the express file and everything will work perfectly fine and you are good to go.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, './public/index.html'));
});
Alright, so I am trying to serve a ejs file to be rendered. This file is inside a different directory, so when I try to write that path it still doesn't work. Here is the problematic code:
app.get('/views2/personal-form', (req, res) => {
res.render('/views2/personal-form');
});
My ejs page is inside the folder views2 inside of the folder views. So as an example all of these following routes minus the one listed above are served:
app.get('/back-home', (req, res) => {
res.render('back-home');
});
app.get('/business', (req, res) => {
res.render('business')
});
app.get('/account', (req, res) => {
res.render('account');
})
app.get('/personal-form', (req, res) => {
res.render('personal-form')
});
I have tried putting the line of code with personal-form in it in numerous places and to no avail. Any recommendations/suggestions would be greatly appreciated. In the picture, you can see the two 'views' folders. I just want to be able to serve view files from multiple view directories so I can organize my app better.
Ok never-mind I just got it.
app.get('/personal-form', (req, res) => { res.render('views2/personal-form') });
NOTE : This is NOT a duplicate question, I've already tried other answers to similar questions.
I'm trying to render html files (Angular) but I'm having an issue.
This works.
app.get('/randomlink', function(req, res) {
res.sendFile( __dirname + "/views/" + "test2.html" );
});
But I don't want to copy and paste dirname thingy over and over, so I tried this in order to not to be repetitive with urls:
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'views')));
app.get('/randomlink', function(req, res) {
res.sendFile('test2.html'); // test2.html exists in the views folder
});
Here's the error.
My express version is 4.13
path must be absolute or specify root to res.sendFile
If you look into the express code for sendFile, then it checks for this condition:
if (!opts.root && !isAbsolute(path)) {
throw new TypeError('path must be absolute or specify root to res.sendFile');
}
So You must need to pass Absolute path or relative path with providing root key.
res.sendFile('test2.html', { root: '/home/xyz/code/'});
And if you want to use relative path and then you can make use path.resolve to make it absolute path.
var path = require('path');
res.sendFile(path.resolve('test2.html'));
You can't go against official documentation of res.sendFile()
Unless the root option is set in the options object, path must be an absolute path to the file.
But I understand that you don't want to copy smth like __dirname every time, and so for your purpose I think you can define your own middleware:
function sendViewMiddleware(req, res, next) {
res.sendView = function(view) {
return res.sendFile(__dirname + "/views/" + view);
}
next();
}
After that you can easily use this middleware like this
app.use(sendViewMiddleware);
app.get('/randomlink', function(req, res) {
res.sendView('test2.html');
});
Easiest way is to specify the root:
res.sendFile('index.html', { root: __dirname });
I was facing the same problem then i solved my issue as follows.
const path = require("path")
app.get('/', (req, res)=>{
res.sendFile(path.resolve("index.html"))
}
Good Luck
the issue happened to me when I was providing subpaths. I set static path and had this route:
const public = path.join(__dirname, "..", "live", "public");
app.get("*", (_, res) => {
res.sendFile("index.html");
});
Visiting "/" path worked but "/anyOtherPath" did not work. So I change the route:
app.get("*", (_, res) => {
res.sendFile(public + "/index.html");
});