Sending javascript in response - javascript

app.get('/',function(req,res){
res.sendFile('index.html');
});
How do i send a javascript file along with index.html back to the client browser for rendering?

You can't send 2 responses, but you could embed your javascript in your index.html file!

The index.html file should contain a reference to the js file in a <script> tag.
You only send the .html.
The browser parses it, sees the reference to the .js file and requests it then.

you can try this
getOptions = (id) => {
return {
root: `uploads/${id}' // specify the path and file Name from where you want to send file
dotfiles: 'deny',
}
}
res.sendFile(id, getOptions(req.body.id));

Related

How to access data sent by node sever using client side javascript

I am using a node sever to send a table from a sqlite db to the browser. This table contains filename and path of a pdf file that I want to render on the browser. Until now I was using hard coded paths for the the pdf file and rendering. But now i have setup a get route and a controller in node such that whenever '/content' is hit in browser , the server queries the database and and sends the data to the client. To the send the data I am using
res.render('content/index',{data:queryData});
Now, how do I access this data using client side javascript so that I can pass the path of the pdf file to the function that renders the pdf? I have done research and the nearest answer I got was using XMLHttpRequest. I tried this method
var xhr = new XMLHttpRequest();
const path = "http://localhost:3000/content";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200)
{
var myResponseText = xhr.responseText;
console.log(myResponseText);
}
};
xhr.open('get', path, true);
xhr.send();
When I do this I get the entire html code for the view. Not the data I expected. How do I solve this issue. I have done some more reading while writing this post and I suppose. I have set a header somewhere? But the documentation says
app.render(view, [locals], callback)
which means res.render can take local variables, shouldn't be setting the headers?
You should return json instead of render template:
app.get('content/index', (req, res) => {
res.json({data: queryData});
});
I am using pdf.js
PDF.js needs the PDF file, e.g.:
pdfjsLib.getDocument('helloworld.pdf')
I'm assuming your queryData goes something like this:
{ filename: 'file.pdf', path: './path/to/file.pdf' }
I'm not sure what's in your content/index or what path this is on, but you obviously need to find a way to make your PDF file ('./path/to/file.pdf') available (as a download). See Express's built-in static server or res.download() to do that.
Once you have the PDF file available as a download, plug that path into PDF.js's .getDocument('/content/file.pdf') and do the rest to render the PDF onto the canvas or whatever.
Hope that helps.

Uploading two files to Node server and receiving a file back using ajax

I have two file inputs and button. When the button is pressed, it should send the two files to the server and wait to receive a file back (the two files processed server-side and the result is returned).
HTML
<input id='file-input1' type='file'>
<input id='file-input2' type='file'>
<button id='send-btn'>
JavaScript (Client)
var input1 = document.getElementById('file-input1');
var input2 = document.getElementById('file-input2');
var btn = document.getElementById('send-btn');
var file1 = null;
var file2 = null;
input1.addEventListener('change', () => file1 = input1.files[0]);
input2.addEventListener('change', () => file2 = input2.files[0]);
btn.addEventListener('click', () => {
if (file1 === null || file2 === null) return;
_sendfiles(file1, file2);
});
function _sendfiles(file1, file2) {
let xmlhttp = new XMLHttpRequest();
xml.open("PUT", "/process", true);
xmlhttp.send({'file1': file1, 'file2': file2});
}
JavaScript (Server)
app.put('/process', (req, res) => {
// Get files from request
// Do stuff with them to generate a third file
// Send generated file back
});
I'm not sure how to receive the files on the server-side, nor how to wait to receive the server's file on the client side. The use of third-party modules is discouraged but not completely out of the question. I'm also not married to the idea of using XMLHttpRequest().
To send files from the client I'd suggest using Fetch + FormData API for convenience:
const formData = new FormData()
formData.append('file1', file1)
formData.append('file2', file2)
fetch(`/api/companies/${id}/logo`, {
method: 'PUT',
body: formData
})
Passing FormData instance to body will automatically set Content-Type: multipart/form-data header.
On the server side I'd suggest using multer since you already use express. You can, of course, implement your own middleware to retrieve files from the request stream if you want to (I didn't do it myself so can't help much).
To receive a file on the client you can do the following (I assume you want this file to be downloaded to the user's file system):
Way #1 (simple):
In the response just send a download URL of this file. Then use this solution to create a link and trigger click event on it. The file will be downloaded by a browser.
Way #2 (not so simple):
On the server use res.sendFile method to send a file (if it's located on fs - otherwise you can send a file Buffer like this for instance).
Then on the client you have response.blob() method to access file blob.
Use a similar trick to download this blob into a file with the help of URL.createObjectURL API.
Additionally, Response API allows you to pipe the stream and do other things with it if you need to (see Streams API).
EDIT (the simplest way)
As Endless pointed out there is a much simpler way actually. I guess I spent too much time dealing with AJAX requests... 🤷‍♂️
You can just submit your HTML form by clicking on submit button, this way a browser will send POST (yeah, can't do PUT this way) request with Content-Type: multipart/form-data automatically since you have inputs with type file:
<form method='post' action='/process'>
<input name='file1' type='file'>
<input name='file2' type='file'>
<button type='submit'>Submit</button>
</form>
So no need to set any event listeners or use any JS in fact.
Then on the server use res.sendFile and add a Content-Disposition: attachment; filename="filename.jpg" header to make sure browser will download it as an attachment and not open it as a webpage.
The biggest disadvantage here is that there is no built-in convenient way in a browser to subscribe to the request's completion event. I.e. there is no success event on the form which you can listen to.
So, if you need it then a nice approach would be to send a cookie from the server along with the file.
On the client set an interval at the moment you submit the form and there check if the cookie exists. If it exists then this means the file is downloaded.

How to download a file in the browser directly from the node.js server side without any variable?

My app is created with mean and I am a user of docker too. The purpose of my app is to create and download a CSV file. I already created my file, compressed it and placed it in a temp folder (the file will be removed after the download). This part is in the nodejs server side and works without problems.
I already use several things like (res.download) which is supposed to download directly the file in the browser but nothing append. I tried to use blob in the angularjs part but it doesn't work.
The getData function creates and compresses the file (it exists I can reach it directly when I look where the app is saved).
exports.getData = function getData(req, res, next){
var listRequest = req.body.params.listURL;
var stringTags = req.body.params.tagString;
//The name of the compressed CSV file
var nameFile = req.body.params.fileName;
var query = url.parse(req.url, true).query;
//The function which create the file
ApollineData.getData(listRequest, stringTags, nameFile)
.then(function (response){
var filePath = '/opt/mean.js/modules/apolline/client/CSVDownload/'+response;
const file = fs.createReadStream(filePath);
res.download(filePath, response);
})
.catch(function (response){
console.log(response);
});
};
My main problem is to download this file directly in the browser without using any variable because it could be huge (like several GB). I want to download it and then delete it.
There is nothing wrong with res.download
Probably the reason why res.download don't work for you is b/c you are using AJAX to fetch the resource, Do a regular navigation. Or if it requires some post data and another method: create a form and submit.

How to download a URL in JavaScript (Nodejs)?

I used this link to make an original link into a download link:
https://milanaryal.com/2015/direct-linking-to-your-files-on-dropbox-google-drive-and-onedrive/
Now how do I actually use that download link to download the file in JavaScript? I want to do something like:
link = 'https://drive.google.com/uc?export=download&id=FILE_ID';
let x = download(link); //now x is the download file
I looked it up and it seems like there are ways of doing this with HTML/jQuery, but I am not using those because I am working on the server side with Nodejs. I am doing this download thing because I want to check if the file is a pdf or text, parse the text, and then search through it using Elasticsearch.
It's easiest to use a module such as Request to do a HTTP get from a node script.
For example:
var request = require('request');
request.get('https://drive.google.com/uc?export=download&id=FILE_ID',
function(err, res, body){
if(err) return console.log(err);
console.log(body);
});
Once the file has downloaded, the callback function is run with the downloaded file in the body variable
If you only want to download the file, open it, search for data and delete it, you can easily edit this code snippet: https://stackoverflow.com/a/11944984/642977

File Download at front end using angular js

On click of download button beside name of a file I am getting the file content from backend . This content is in the bytes . The file can be of any type . How to convert the data received from backend to file and download it automatically on receiving response(file Content) .New bee in html and angular js .Any pointers or suggestions needed :)
You will need to have your backend tell your front-end the location of the file, and then the front end can place a link to the file. The backend should probably generate a unique hash name for this file.
The actual file can be returned as part of a Rest GET request as long as the backend webserver has the correct mime types configured.
So in your controller you would call a service to get the file path:
SomeController.$inject = ['$http'];
var SomeController = function($http) {
var self = this;
$http.get('/download-file-path').then(function(path) {
self.path = path;
}
}
Then in your view
<div ng-controller='SomeController as vm'>
<a ng-href="{{vm.path}}">Download</a>
</div>
When angular calls GET: /download-file-path the backend should return the name and path of the file, say something like /download/file-7dje79ae.xml. Then angular puts this path in the a link. When the user clicks the download button, the users browser will then make a request to /download/file-7dje79ae.xml and download the file.

Categories