How to download file from Server in React.js [duplicate] - node.js

I want to perform a javascript xhr request for a png file from a C# webserver which I wrote.
Here is the code I use
var imgUrl = "http://localhost:8085/AnImage.png?" + now;
var request = new XMLHttpRequest();
request.open('GET', imgUrl, false);
request.send(); // this is in a try/catch
On the server-side I send back the file and add a Content-Disposition header.
I obtain the following response
I made sure that Content-Disposition was attached in the headers after the Content-Type (the screenshot is from Firebug, which appends in alphabetical order).
The results is that no dialog box is triggered, am I missing something in the response?
edit:
I want to perform everything in javascript for several reasons.
First: I don't want to show the image and I want to keep everything behind the curtain.
Second: when requesting the image I want the Content-Disposition to be added only on particular requests. Such requests are marked with a "Warning" header with value "AttachmentRequest"
request.setRequestHeader("Warning","AttachmentRequest");

I don't think Content-Disposition triggers any file save dialog when the request is via XHR. The use of XHR suggests you're going to handle the result in code.
If you want the user to be prompted to save the image to a file, I've used this technique successfully:
window.open("http://localhost:8085/AnImage.png?" + now);
It has the downside that it flashes a blank open window briefly until the header arrives, then the new window closes and the "save file" dialog box appears.
Using an iframe may prevent the window flashing:
var f = document.createElement('iframe');
f.style.position = "absolute";
f.style.left = "-10000px";
f.src = "http://localhost:8085/AnImage.png?" + now;
document.body.appendChild(f);
Separately, I wonder what effect (if any) Content-Disposition has on the handling of an img element:
var img = document.createElement('img');
img.style.position = "absolute";
img.style.left = "-10000px";
img.src = "http://localhost:8085/AnImage.png?" + now;
document.body.appendChild(img);
I haven't tried that, but the browser might respect the header. You'd need to be sure to test on all of the browsers you want to support.

Related

Why is Chrome treating this file as document, while Firefox as Image?

I have a download GET endpoint in my express app. For now it simply reads a file from the file system and streams it after setting some headers.
When i open the endpoint in Chrome, I can see that this is treated as a "document", while in Firefox it is being treated as type png.
I can't seem to understand why it is being treated differently.
Chrome: title bar - "download"
Firefox: title bar - "image name"
In Chrome, this also leads to no caching of the image if I refresh the address bar.
In Firefox it is being cached just fine.
This is my express code:
app.get("/download", function(req, res) {
let file = `${__dirname}/graph-colors.png`;
var mimetype = "image/png";
res.set("Content-Type", mimetype);
res.set("Cache-Control", "public, max-age=1000");
res.set("Content-Disposition", "inline");
res.set("Vary", "Origin");
var filestream = fs.createReadStream(file);
filestream.pipe(res);
});
Also attaching images for Browser network tabs.
This are all to do with the behaviors of Chrome, you can test on another site like Example.png on Wikipedia.
Chrome always treats the "thing" you opened in the address bar as document, ignoring what it really is. You can even test loading a css and it will read document.
For title, it reads download because your path is /download, you cannot change it according to this SO thread.
For caching, Chrome apparently ignores the cache when you are reloading, anything, page or image. You can try using the Wiki example.png, you will get 304 instead of "(from cache)". (304 means the request is sent, and the server has implemented ETag, if-none-match or similar technique)

How to pass password only to HTTP request?

I am using JavaScript in the scripting engine in a program called Directory Opus. It seems to use a flavor of JavaScript more like MS JScript. I mention that because to say not all things JavaScript (ES6) will work with what it accepts. My question is this: in a HTTP request like the code I show should I be able to pass user credentials to the open command if only a password is required? This request is for VLC player and their instructions are to leave the username blank. If put the same URL in a browser it will prompt with a password once, I will put in the password “vlcremote”, leave the username blank and it will return the status. When I use with the syntax, I show, it returns an error when the open command uses “” as a username. If I put a random user name the request returns a limited result but denies access to the data it should give. Is there a better way to do this?
function getValues(webUrl)
{
var xhr = new ;
var url = webUrl;
xhr.open("GET", url, false, "", "vlcremote");
xhr.setRequestHeader("Content-type", "text/xml");
xhr.setRequestHeader("Authorization", "Basic")
xhr.send()
DOpus.Output(xhr.readyState)
var xmlText = xhr.responseText;
DOpus.Output(xmlText)
}
getValues("http://127.0.0.1:8080/requests/status.xml");

Chrome extension download file without prompt

I'm making an extension in which the user is setting some configs and, based on his selection, a png file needs to be downloaded (from a remote url) in the background and saved as a file somewhere to make it accessible later. It must be saved as a file and also injected in the page by it's final path.
Reading the [fileSystem][1] api of chrome, all methods are sending a prompt to the user in order to download a file. Is there any way I can save files to a location without prompting the user for download?
In an effort to close this years old question, I'm quoting and expanding on wOxxOm's comments and posting as an answer.
The key is to download the raw data as a blob type using fetch. You can then save it via an anchor tag (a link) using the download attribute. You can simulate the "click" on the link using JavaScript if you need to keep it in the background.
Here's an example (more or less copied another SO post).
const data = ''; // Your binary image data
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
const blob = new Blob([data], {type: "octet/stream"}),
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName; // Optional
a.click();
window.URL.revokeObjectURL(url);
This is not without its faults. For instance, it works best with small file sizes (exact size varies by browser, typically ~2MB max). The download attribute requires HTML5 support.

Delay the opening of other tabs, until the first tab loads completely

I am creating a Chrome Extension, using JS that takes a user prompted URL parses some variables out of it, and then loads multiple tabs based on the information that was parsed. The issue, is that before I can do that, I need to wait for a login tab to complete loading, before trying to open the other tabs. So the preferred order would be
User Prompt
Load Login Tab
Wait until Login Tab is loaded
Open remaining tabs.
My code is as below
var URL_Proper = prompt ('Paste the Become-User-ID URL below:');
var User_ID = URL_Proper.substring(URL_Proper.indexOf('?become_user_id=')+16,URL_Proper.length);
var Domain = 'https://' + URL_Proper.substring(8,URL_Proper.substring(8,URL_Proper.length).indexOf('/')+8);
var win = window.open(Domain + 'login_key', '_blank');
var win = window.open(URL_Proper, '_blank');
var win = window.open(URL_Proper.substring(0,URL_Proper.indexOf('?')), '_blank');
var win = window.open(Domain.substring(0)+'/users/'+User_ID, '_blank');
The delay I would like would be between the (Domain + 'login_key', '_blank'); and the other three tabs, but I can't for the life of me figure it out. My guess is this would be better served with chrome.tabs.create, but I am such a beginner that I can't figure out how to do that, nor can I figure out how to make the code wait for the first tab to load, before opening all the other tabs.
Thank you.

Web Api HttpResponseMessage not returning file download

I am currently doing a POST to a Web Api method and am posting an array of objects. When I get to the method, my parameters are resolved properly, and I make a call to the DB and return a list of records.
I then take those records and convert them to a MemoryStream to be downloaded by the browser as an Excel spreasheet. From there, I create an HttpResponseMessage object and set properties so that the browser will recognize this response as a spreadsheet.
public HttpResponseMessage ExportSpreadsheet([FromBody]CustomWrapperClass request){
var result = new HttpResponseMessage();
var recordsFromDB = _service.GetRecords(request);
MemoryStream export = recordsFromDB.ToExcel(); //custom ToExcel() extension method
result.Content = new StreamContent(export);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.Name = "formName";
result.Content.Headers.ContentDisposition.FileName = "test.xlsx";
return result;
}
Instead of seeing the spreadsheet being downloaded, nothing seems to happen. When I check the developer tools (for any browser), I see the Response Headers below while the Response tab just shows binary data. Does anyone know what I might be missing here?
How are you doing your POST? It sounds like you might be trying to this via a javascript AJAX call, which cannot be done (https://stackoverflow.com/a/9970672/405180).
I would instead make this a GET request for starters, and use something like window.location="download.action?para1=value1....". Generally web api Post requests are made to create a file/entry, not retrieve one.
Alternatively, you could use a HTML Form with hidden elements corresponding to your query parameters, and use javascript to submit the form.

Resources