Express.js - How to serve files from an arbitrary directory? - node.js

I'm trying to serve an arbitrary directory (from a node.js app), but I keep getting Cannot GET /
var express = require('express');
var app = express();
app.use("C:/test/", express.static('C:/test/'))
I want it to display a webpage that shows a list of files (of the specified directory) and the download link. So that when I visit the URL from local devices I would see something like:
C:/test/file1.png - download link
C:/test/file2.mp4 - download link
Is that possible?

It looks like the easiest way to send a single file is to use download method:
app.get('/uniquePathHere', function (req, res) {
res.download('C:/test/1.png', '1.png');
})
On a local device open the IP of the server (IPv4 address assigned by the router to the computer), for example:
192.168.0.105:3000/uniquePathHere
And it will start downloading automatically
If you want to display all the files of the directory, you can use the solution suggested in the comments:
app.use('/ftp', express.static('C:/test/'), serveIndex('C:/test/', {'icons': true}))
And then visit IP of the server, for example:
192.168.0.105:3000/ftp
How to get server IP
var ip = require("ip")
console.log(ip.address())

Related

How to get IP address of Computer, in which the node js server runs, to use in react application?

I wanna get the IP address of the computer that the node js server runs in, in order to use the correct URLs of the server inside React application.
for example when I fetch a "http://localhost:<port>/api" from another device in the same network it doesn't work.
I tried to provide the computer IP address manually, but after sometime, a day or two, the IP changes and then I have to open provide the IP address again.
so, I'm asking if there's a way to provide the IP address dynamically to React application?
You can either use the Node networkInterfaces Out Of the Box feature, or use a package that handles parsing request and extracting data for you.
const os = require('os');
const networkInterfaces = os.networkInterfaces();
console.log(networkInterfaces);
If you do not want to parse the response yourself - have a look at highly popular package: request-ip.
https://www.npmjs.com/package/request-ip
const requestIp = require('request-ip');
// inside middleware handler
const ipMiddleware = function(req, res, next) {
const clientIp = requestIp.getClientIp(req);
next();
};
for anyone facing the same problem, I found a simple solution which is to specify a "proxy" in package.json file of the React application:
in package.json file
...
"proxy": "http://192.xxx.xx.xxx:<port>"
...
this way you're telling react to proxy the requests to the backend server when making a request for example to "/api/v1" instead of specifying the whole url like this "http://192.xxx.xx.xxx:<port>/api/v1"
and whenever the IP changes you just edit the "proxy" value and restart the dev server.

cannot reach a file on server though I exposed using express

In my project I need to store some text files dynamically and end user should be able to download them from browser. I know the best way is using object store like MINIO or S3 but unfortunately the only way I have is to use in memory storage. So what I am trying to do is: I made a public folder and I exposed it using the following code:
var express = require('express');
var app = express();
//setting middleware
app.use(express.static( 'public')); //Serves resources from public folder
var server = app.listen(5000);
it is as simple as that. Then for testing just to make sure I can download and reach a file I created a public folder with t.txt file in it and when I try:
http://localhost:5000/public/t.txt
I get
So why am I not getting it? Also is what I am trying to achieve will be a good match to scenario and is it doable at all?
When you're not specifying a path in app.use(), your app will serve the contents of the directory you're pointing to in express.static() on the root path. Try this:
http://localhost:5000/t.txt
That said, if you want it to be accessible at /public/t.txt, just specify the path:
app.use('/public', express.static('public'))
At first use the following line of code:
app.use(express.static(__dirname+'/public'));
This means that your home directory for static HTML pages is in the "public" folder. Note that the "__dirname" points to the directory of the current js file.
After that, call the following URL from the browser or POSTMAN:
http://localhost:5000/t.txt
As you can see, there is no need to write http://localhost:5000/public/t.txt referring to the "public" folder because you have already specified that in the app.use line.

Using Node to access FTP in another server

I need to access FTP in another server (Ubuntu).
My Node.js API receive an image from user, and then needs to upload it to another server using FTP connection. However, if user folder doesn't exist, I need to create folder before sending the image.
How can i do this?
I'm using express-upload to get files:
const express = require('express');
const upload = require('express-fileupload');
const app = express();
app.use(upload());
app.use('/upload', async (req, res, next) => {
console.log(req.files.image);
})
You can use Basic FTP, an FTP client module, and use its ensureDir() method to implement the requirement "if user folder doesn't exists, I need to create folder before sending image".
According to its document:
...we make sure a remote path exists, creating all directories as necessary.
await client.ensureDir("my/remote/directory")
Then, you can send the image using its upload() method.

Is it possible to host web page with angular.min.js functionality using nodes http module

Is it possible to host web page with angular.min.js functionality using nodes http module?
I'm making a really simple web project that is going to fetch some data and I decided to use angular.js to display data no the page. I tried to read index.html using fs module and sent it as response to the localhost. It seems that angular.min.js, that was included in the pages head section did not load as it would when I run the page in the browser from the file explorer.
angular is a web application, so, please serve the angular using your node.js server and load the app in the web browser.
add a listener of get then send all files that index.html need, it is done.
or use app.use(express.static('public')); which public is your 'public' folder, put all file in dist to serve as a static content.
I use the first option every time but it is trick but functional.
sample code is:
const express = require('express');
const router = express.Router();
const path = require('path');
router.get('/:id',(req,res)=>{res.sendFile(path.join('/path/to your/file/'+req.params.id));});
router.get('/',(req,res)=> res.sendFile(path.join('/path/to/your/file/index.html'));});
module.exports = router;

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.

Resources