Send non-public file as attachment in response (download non-public file) - javascript

I have a download button in HTML that when is clicked a POST request is made via ajax sending the filename of the file that must be downloaded.
On the server side I do something like this:
function download (req, res) {
...
// path is an absolute path to a file that is not in the public
// directory. I want to download that file
res.writeHead(200, {
"Content-disposition": "attachment;filename=\"" + path + "\"",
"Content-Type": "text/csv"
});
var filestream = fs.createReadStream(path);
filestream.pipe(res);
};
I can see the file content in the response but the save file dialog doesn't appear.
Which is the issue? How can I fix this?
I use only built-in node modules, so I don't use express.

You can't force a browser to show a Save File dialog.
With your example, on my Mac both Chrome and Safari download the file automatically (in Chrome it's a setting whether or not to show a dialog which – I think – is turned off by default; I don't know if Safari has a similar setting), whereas FireFox does give me a dialog.

Related

Office Document is corrupt after downloading; Node.js

I'm developing a Node.js Server. This Server makes Calls to an API. You can send Files to the Node.js Server and that Server will send those File to another API that will process the File. When the API processed the File, the Node.js Server will download the File and send it to the Requestor. This Requestor can download the File.
Now when I try to make the request with Microsoft Office Files like .docx or .pptx, they corrupt. However it works perfectly fine with a .txt File for example.
The Data I send back to the Client looks something like this:
[Content_Types].xml��MN�0►��↕y�↕7,►BM��P�^��'���dO��Ƃ#q♣&)♦�*�R�������y{y↔O��dk�I{W��↑�♀��J�E�V���lR�g�)�V�*�D♀7�'�♦+R�♥8�4>Z�t�♂▲�|▬♂����§��!8̱�`��♫→�2��o��▲K�,�������►��☻�
��N���i�♦����H☺��☻��H�◄5��N�▼�E0�8�G��&�����♂�H��ZA6§◄▼�%=Nަd&Q��☺?����T��▼§wr�N[5☻KH��♣k��b�v�F60⌂☻D�M������t6�▲pg�∟♫:�a>�]���,˓}tB�317⌂�C�{��♣�~R�;PK☺☻¶�n&V,&3�u☺0♥►docProps/app.xmlPK☺☻¶�n&V��i��☺�☻◄�☺docProps/core.xmlPK☺☻¶�n&V⯨��☻)♂◄\♥word/document.xml
PK☺☻¶�n&V�
!♦�♂◄�word/settings.xmlPK☺☻¶�n&V�♠�Ys♂↔s☼8♀word/styles.xmlPK☺☻¶�n&V��m��♠� ↨�↨word/theme/theme111.xmlPK☺☻¶�n&V�/�⌂�☺z♠↕�▲word/fontTable.xmlPK☺☻¶♥�n&Vψ��D☻D☻♂� _rels/.relsPK☺☻¶�n&V��V=�F♥∟/#word/_rels/document.xml.relsPK☺☻¶�n&V�l8=C☺�♦‼R$[Content_Types].xmlPK♣♠♂♂�☻�%
The Error of Word looks like this:
enter image description here
Does anyone know what I'm doing wrong.
(It's the first Node.js Server i'm developing btw, so please don't be too harsh with me)
Here's what I have so far:
app.post("/document", upload.single('file'), async (req, res) => {
// Code to upload the Document to the API
await axios.post(
`${API_BASE_URL}/document/${id}/result?auth_key=${API_KEY_VALUE}&document_key=${key}`
).then(( data ) => {
console.log("return data");
console.log(data.headers);
res.setHeader('Content-Type', data.headers['content-type']);
res.setHeader('Content-Disposition', data.headers['content-disposition']);
res.setHeader('Content-Length', data.headers['content-length']);
res.setHeader('Connection', data.headers['connection']);
res.setHeader('Date', data.headers['date']);
res.setHeader('x-trace-id', data.headers['x-trace-id']);
res.setHeader('strict-transport-security', data.headers['strict-transport-security']);
res.setHeader('access-control-allow-origin', data.headers['access-control-allow-origin']);
res.send(data.data);
})
})
I can always download the Document in the right File Type etc. but when I try to open it, it says something like "can't read the File":

Error downloading XLSM file from angular application

I have an XLSM (macro enabled with sheet level formatting) file in my repository. I have used 'xlsx-populate' node library to read the file, add rows and save it in the repository successfully. I pass the work book to front end, setting the headers and MIME type for XLSM file, the file gets downloaded but upon trying to open it says 'Excel cannot open the file because the file format is not valid. Verify that the file has not been corrupted and that the extension matches the format of the file'. The same flow is successfully working for an XLSX file though. Is it possible that angular supports XLSM file download (possibly) with any alternative library? Is it the way in which the content is being sent that needs alteration? I am also open to any alternative approaches/suggestions.
MIME type for XLSM: application/vnd.ms-excel.sheet.macroEnabled.12
Code snippet:
this.content = XlsxPopulate.fromFileAsync(__dirname + "myFile.xlsm");
downloadFile(req,res) {
res.setHeader('Content-Type', xlsmMimeType);
res.setHeader('Content-Disposition', 'attachment; filename=myFileName');
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
res.send(this.content)
}

Cannot download pdf from file-saver.js react

I am trying to download the pdf from this url :
http://www.africau.edu/images/default/sample.pdf
I followed the example and wrote the code below.
import { saveAs } from "file-saver";
const downloadPDF = ()=>{
var FileSaver = require("file-saver");
FileSaver.saveAs(
"http://www.africau.edu/images/default/sample.pdf",
"somehthing.pdf"
);
}
However, when the downloadPDF function is invoked on the button pressed. The file is not being saved. The pdf is simply being opened in the new tab.
The screenshot of what the pdf looks like in the new tab is shown below.
How do I save the pdf file?
Also, is this approach to get the pdf even valid in the first place or is axios.get() more preferred approach to get the file, then save the response file (response.body) via FileSaver.saveAs()
If the question is unclear, please let me know in the comment before flagging - I will make the necessary update. Thank you
seems like the FileSaver does not help.
However if the file is coming from the server we recommend you to first try to use Content-Disposition attachment response header as it has more cross-browser compatiblity.
as far as I know, there are 2 ways to download file in browser.
server returns a response with header Content-Disposition with value attachment or header Content-Type with value application/octet-stream. Browser will promote the SaveDialog and handle this download for you. This is preferred way to download but this requires you to have control over the server.
you just use ajax or axios to get the data of any file at anywhere. then you create a dummy link to download (like this one). then browser will promote for SaveDialog and then save file to disk. This is just fine for small file but not for large files because you have to store entire file in memory before saving it to local disk.
I think option 2 is appropriate for you.
Example here. In this example, I place a file named abc.json in public folder. Note that the server must enable cors for your website origin. otherwise, there's no way for you to access that file in javascript code.

Node.js - download and save PDF file locally for offline - file damaged

I currently have a desktop App built with Node Webkit. When the user is online, the App will open up PDF files from the server. I then save these files locally so they are available when offline.
I am using the Node.js File System's fs.writeFile(), to save the PDF locally but when trying to open it via the App the PDF is blank. When I try to open it direct from the folder I get the below error.
Can anyone please advise?
//save PDF file for offline
function saveFile(pdfvar) {
var filename = 'test.pdf';
fs.writeFile(filename, pdfvar);
}
//open PDF in new window
$('#stage').on('click', '#pdflink', function(event){
var pdfvar = (this.getAttribute('data-pdffile'));
window.open(pdfvar, "_blank");
if(online===true){
saveFile(pdfvar);
}
});
Are you holding entire content of a PDF in a DOM element attribute this.getAttribute('data-pdffile') ? This is where it may get corrupted.
When you call
window.open(pdfvar, "_blank");
the content is not ready to be opened like that. It should be first converted to base64 encoded url.
window.open('data:application/pdf,' + escape(pdfvar));
UPDATE:
The actual problem was that the OP was trying to save the file using it's URL in "pdfvar"
fs.writeFile(filename, pdfvar);
but the file created was containing only a URL itself. What was required was downloading the file first using a http library:
How to download a file with Node.js (without using third-party libraries)?

Static image file is invisible in node.js/express

The following code is an exemple of code to serve static files in express on node.js. If I ask the server a .css file there is no problem, but if I ask an image such as a jpg or png, it loads a white page (no /GET error or anything, a simple white page). In my developer tool in my browser I see the following warning: 1Resource interpreted as Document but transferred with MIME type image/jpeg. How can I fix this?
I am using cloud9ide and express 2.4.6
var express = require("express"),
app = express.createServer();
app.use(express.static(__dirname + '/static'));
app.get('/', function(req, res){
res.send('Hello World');
});
app.listen(process.env.C9_PORT);
It looks like the file in question is not in JPEG format. Can you save that URL as a file using wget, curl or similar tools and open that file in a text editor?
A valid JPEG file should look like binary garbage and should have "JFIF" signature string close to the beginning (byte offset 6 I think).
it is possible that the file contains an error message instead of valid JPEG data.
It seems to be a bug from cloud9 ide. I tried my code locally and it worked. There is a ticket open on cloud9ide at: http://cloud9ide.lighthouseapp.com/projects/67519/tickets/390-get-png-image-not-working-in-preview-mode#ticket-390-4

Categories