Downloading File From Client Side Node.js - javascript

so I am trying to build a website that allows users to download files that are located in the server computer when the users access the website and click a download button.
I wish to use as few libraries as possible due to some real world limitations. Ideally no Express or Ajax. And I think it should be fully possible with just vanilla node.js
From my search on the internet it seems most of the code is of this form:
const fs = require('fs');
const https = require('https');
// URL of the image
const url = 'GFG.jpeg';
https.get(url,(res) => {
// Image will be stored at this path
const path = `${__dirname}/files/img.jpeg`;
const filePath = fs.createWriteStream(path);
res.pipe(filePath);
filePath.on('finish',() => {
filePath.close();
console.log('Download Completed');
})
})
However, the code doesn't seem to be doing what I want.
First, it requires an url, so it is more about directing a resource online to another location. Whereas I want to actually serve a locally stored file on the server to users when they access the website.
Second, it appears to be downloading to the server computer. But what I want is to let users download to their own client devices. Basically the normal download function you would encounter when you want to download something on the Internet and you see your browser's "Download" section having some new entries.
How can I achieve what I want?
I'm a total noob at this, so it would be great if I can get a skeleton code with some dummy file or pathname.
Appreciate any guidance. Thanks!

You are missing an http.server. http.get just does a web request and as you said you don't want to do that.
Here is some example code creating a server and serving a single file without using express:
const fs = require('fs');
const path = require('path');
const http = require('http');
http.createServer(function(request, response) {
var filePath = path.join(__dirname, '/files/img.jpeg');
response.writeHead(200);
var readStream = fs.createReadStream(filePath);
readStream.pipe(response);
}).listen(2000);

Related

Access all files within a given folder (The File System Access API)

Can I use the File System Access API (https://web.dev/file-system-access/) to create something like a file explorer within a website (react).
I plan to make a simple online file explorer that lets you browse open a folder and then lets you browse through the folder, play videos and MP3s.
(I know this wasn't possible a few years ago, because it was impossible for js to access anything in the local storage, I just wanted to know if anything have changed or not. If File System Access API is not the way to go, can you suggest some better way to read bulk local files from a folder.)
This is possible with the File System Access API today:
const dirHandle = await window.showDirectoryPicker();
for await (const entry of dirHandle.values()) {
console.log(entry.kind, entry.name);
}
You can explore the folder structure by going deeper if entry.kind is a directory.
For future reference, I'm posting my work; https://github.com/akshayknz/filesystem-access-api/blob/main/file.html (A html page which displays all images from picked folder.)
Note:The API only work in secure contexts (i.e. it works in https:// and file:///)
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const contents = await file.text();
or
const dirHandle = await window.showDirectoryPicker();
const fileHandle = await dirHandle.getFileHandle(entry.name, {});
const file = await fileHandle.getFile();

Reading from & writing to files in same domain using JavaScript

Say I have a website hosted via Bluehost or the like, at example.com. If I have a file stored at example.com/a.txt, how can I go about reading from this file? And, if I want to write a new string to this file, is it possible to do so, or is it impossible with JavaScript in the web?
you could make a simple api using express and use file-system or fs
with that package you can do that with a single line after doing const fs = require("fs"); :
const constant = fs.readFileSync("path"); //read the file
fs.writeFile("path", "something to write", () => {
//a callback func
});```
In short no. But you have workarounds:
You can open some folder for the public view:
static files - read only access (styles and javascript)
media files - read only access (pictures and other media)
some manually created url - to edit/create the file in the media folder

Express downloadable response from stream

I have an end point which should respond back with an excel file. Right Now I'm able to write the file to a write stream,pipe it to the disk and respond with the downloadable file.
var fs = require('fs');
const writeStream = fs.createWriteStream('abc.xlsx');
//stream is the stream object
stream.pipe(writeStream);
res.download('abc.xlsx')
This works fine and the browser downloads abc.xlsx file. Is there anyway I could do this without storing the file to the disk just by using the stream object?

downloading binary file over REST API

I've got a big system where I need to generate a PDF file. I'd like to access it via REST API and, of course, store the file locally.
The file content depends on many parameters what the content of this file should be, i.e. time: from-to, filters, sorting and many, many more parameters; they form a JSON object which perfectly fits into POST parameters. The parameters cannot go through GET, since they're too big.
There is the FileSaver library that works perfectly fine on modern browsers. I created an online demo. But when I downloaded old browsers - firefox11, firefox12, firefox15, it didn't work at all, even though I included the Blob.js polyfill - it opened a new tab with URL like: blob:457-343457-34574567-4576456 that was unable to be saved. I need to support many browsers, not only the new ones.
The question is - I've got JSON parameters object inside my SPA app - how should I design this PDF binary file download?
I was thinking of 3 approaches:
force browser to create a file on localhost - using FileSaver. WOrks fine for modern browsers, doesn't work for old ones
create downloadable link. I shoot a POST to the REST API, incuding all parameters, the REST API returns something like: {"download": "mysite.com/download/ms2h5d34h53m"}, the response is used to display a link to the user; the user might click the link (with no AJAX) and the server-side API should just return a file like in the old times.
not mine, but somewhere I read I could create an invisible form that shoots a POST to the server, which triggers file download (perhaps this would reduce the step with returning the {"download": "mysite.com/download/ms2h5d34h53m"} JSON)
I need a guidance on how to do that right.
I tried to create a test express.js server below. When I access http://localhost:8081/download directly, I see a PDF file downloaded locally. But when I try to access it via ajax/js:
then the content is fetched as binary stream:
var fs = require('fs');
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
});
app.get('/download', function(req, res){
var file = fs.readFileSync(__dirname + '/example.pdf', 'binary');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Length', file.length);
res.setHeader('Content-Disposition', 'attachment; filename=new-name.pdf');
res.setHeader('filename', 'sample.pdf');
res.write(file, 'binary');
res.end();
});
var server = app.listen(8081, function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
});

Is there anyway to copy/upload/edit a file with javascript?

I have two servers, Server1 & Server2. I want to copy a file from Server1 to Server2 with JavaScript. Is this possible? If so, how?
For example, last week I used "wget" command for this action. Now I want to handle it with JS.
i don't know the full specifications for the task at hand, but you could look into using Node.js to assist with your issue. here's a quick repo that might help repo or you could use this snippet i took from similar post:
var http = require('http');
var fs = require('fs');
var google = http.createClient(80, 'www.google.com');
var request = google.request('GET', '/',
{'host': 'www.google.com'});
request.end();
out = fs.createWriteStream('out');
request.on('response', function (response) {
response.setEncoding('utf8');
response.on('data', function (chunk) {
out.write(chunk);
});
});
i hope this helps, and here's the original post
Nope. You can't access disk from JavaScript. Just for a moment think of security problems it can bring with itself. I simply create a web page, and when you visit it, I upload all the images of your girlfriend and publish them (just kidding, but that's the security problem it poses).
However, JavaScript can access files on some scenarios:
When user selects some files using <input type='file' /> element
Using HTML5's offline-storage (I guess this one, not sure).
However, if you want, you can use Node.js to do that. However, this is a server-side stuff.

Categories