Starting download of an url shortcut file? - javascript

I have created a shortcut file by going to Desktop -> new shortcut and entered link.
Now I have uploaded this shortcut file (*.url) on the
root on my server as shortcut.url
When i directly access mysite.com/shortcut.url, it does not start the download of it but instead show the content of the .url file.
Now on my page where i link to mysite.com/shortcut.url, I have tried the following methods:
How to start automatic download of a file in Internet Explorer?
But noone of them seems to work in Chrome (I though that if it their answers work in IE then Chrome it would too).
How is it possible to start downloading of this type of file, on click?

Generally speaking, a browser will fetch a resource in download mode (rather than displaying directly) if the content type is one that it cannot handle, and no plugins can handle. The easiest way for that to be the case is by using the content type for generic binary files:
Content-Type: application/octet-stream
Basically, configure your web server to use this content type (often called a MIME type) for .url files. How you do that depends on what server you're using.

Related

How to serve blob and have good filename for all users?

I have a PDF file as a blob object. I want to serve to my users, and right now I'm doing:
html = '<iframe src="' + URL.createURL(blob) + '">';
That works fine for people that want to use their in-browser PDF tool.
But...some people have their browser set to automatically download PDFs. For those people, the name of the downloaded file is some random string based on the blob URL. That's a bad experience for them.
I know I can also do:
<a href="blobURL" download="some-filename.pdf">
But that's a bad experience for the people who want to use in-browser PDF readers, since it forces them to download the file.
Is there a way to make everybody have good file names and to allow everybody to read the PDF the way they want to (in their browser or in their OS's reader)?
Thanks
At least looking at Google Chrome, if the user disables the PDF Viewer (using the option "Download PDF files instead of automatically opening them in Chrome") then window.navigator.plugins will show neither "Chromium PDF Plugin" nor "Chromium PDF Viewer". If the option is left at the default setting, the viewer will show in the plugin list.
Using this method, one can utilize window.navigator.plugins to check if any of the elements' names are either of the aforementioned plugins. Then, depending upon that result, either display a <iframe> or a <a href="blobUrl" download="file.pdf">. For other browsers I imagine that different methods would have to be used. You can also check for a "Acrobat Reader" plugin, which some machines may have instead, or even just the word "PDF".
On a side note, it does look like it is possible to detect if the default Firefox PDF viewer is enabled by using http://www.pinlady.net/PluginDetect/PDFjs/ .
Try to append &filename=thename.pdf to the binary, metadata or http header:
Content-Disposition: attachment; filename="thename.pdf"
I have looked through the documentation of createObjectURL(blob), it will always return a unique and specific format of url. It is not possible to change the URL here.
The plugin thing is not consistent across browsers.
Now here is my radical idea
Find or create(if not available) a js library that can create and save PDF files to server from blob. (I looked through some of them like 'jsPDF','pdfkit' but none of them use blob)
Save the file to server with a valid name
use the above name in the iframe.

node/express Force browser to download file with custom name

I've built a node/express website for my university project that, after searching for an ID of a law, it shows a big table with all files in different formats and languages related with this id.
I use the module "http-proxy" to request and serve these files to client.
Nothing wrong when serving xml, xhtml, html and pdf files (every browser is able to directly view them).
I have problems with .zip and .rdf files. Files are not corrupted but they are losing the original name
when i click on ZIP icon, it gives me the download prompt, but I'm losing the original file name (the file will be called "proxy" or "proxy.zip", different behaviors on different browsers)
when i click on RDF icon, some browsers opens the file directly in browser, some browsers won't recognize the format, some browsers wants to download it with name "proxy")
So I discovered the HTML5 attribute "download" of the tag "a". It just solve my problem, anyway it is not supported on every version of Internet Explorer and Safari. Surfing the web I found some workarounds to add "Right click and save as..." after a div link when the page is viewed in IE or Safari, but this solution is not for me, because i'm not talking about a single link but a table full of links. And my site need to work also on mobile phones.
Is there any way to write some server-side code to force browsers to download files with a custom file name?
Here is the small piece of code of the proxy:
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({ ignorePath: true });
app.get('/proxy', function(req , res) {
var file = req.query.file;
var realurl = 'http://'+cfg.edb_opt.host+':'+cfg.edb_opt.port+cfg.edb_opt.rest+file;
console.log('Proxy: serving '+realurl);
proxy.web(req, res, { 'target': realurl });
});
All cfg* variables comes from a json configuration file to set the host, port, and starting path where files are contained.
Thanks in advance :)
You need to add a new header to the response object to indicate the file name and do a regular download.
res.set("Content-Disposition", "attachment;filename=somefile.ext");
You could also use "inline" if instead you want the browser to try to open the file within it self, like with Chrome does with pdf files.
res.set("Content-Disposition", "inline;filename=somefile.ext");
As per #Thomas suggestion, also is a good idea to include always the right content type:
res.set("Content-Type", "application/octet-stream");
In Express 4 and later, there are 2 helper functions to change the content-type and specify attachment disposition:
res.type("application/octet-stream");
res.attachment("filename.ext");
See docs for type and attachment.

Chrome extension: How to show custom UI for a PDF file?

I'm trying to write a Google Chrome extension for showing PDF files. As soon as I detect that browser is redirecting to a URL pointing to a PDF file, I want it to stop loading the default PDF viewer, but start showing my UI instead. The UI will use PDF.JS to render the PDF and jQuery-ui to show some other stuff.
Question: how do I make this? It's very important to block the original PDF viewer, because I don't want to double memory consumption by showing two instance of the document. Therefore, I should somehow navigate the tab to my own view.
As the main author of the PDF.js Chrome extension, I can share some insights about the logic behind building a PDF Viewer extension for Chrome.
How to detect a PDF file?
In a perfect world, every website would serve PDF files with the standard application/pdf MIME-type. Unfortunately, the real world is not perfect, and in practice there are many websites which use an incorrect MIME-type. You will catch the majority of the cases by selecting requests that satisfy any of the following conditions:
The resource is served with the Content-Type: application/pdf response header.
The resource is served with the Content-Type: application/octet-stream response header, and its URL contains ".pdf" (case-insensitive).
Besides that, you also have to detect whether the user wants to view the PDF file or download the PDF file. If you don't care about the distinction, it's easy: Just intercept the request if it matches any of the previous conditions.
Otherwise (and this is the approach I've taken), you need to check whether the Content-Disposition response header exists and its value starts with "attachment".
If you want to support PDF downloads (e.g. via your UI), then you need to add the Content-Disposition: attachment response header. If the header already exists, then you have to replace the existing disposition type (e.g. inline) with "attachment". Don't bother with trying to parse the full header value, just strip the first part up to the first semicolon, then put "attachment" in front of it. (If you really want to parse the header, read RFC 2616 (section 19.5.1) and RFC 6266).
Which Chrome (extension) APIs should I use to intercept PDF files?
The chrome.webRequest API can be used to intercept and redirect requests. With the following logic, you can intercept and redirect PDFs to your custom viewer that requests the PDF file from the given URL.
chrome.webRequest.onHeadersReceived.addListener(function(details) {
if (/* TODO: Detect if it is not a PDF file*/)
return; // Nope, not a PDF file. Ignore this request.
var viewerUrl = chrome.extension.getURL('viewer.html') +
'?file=' + encodeURIComponent(details.url);
return { redirectUrl: viewerUrl };
}, {
urls: ["<all_urls>"],
types: ["main_frame", "sub_frame"]
}, ["responseHeaders", "blocking"]);
(see https://github.com/mozilla/pdf.js/blob/master/extensions/chromium/pdfHandler.js for the actual implementation of the PDF detection using the logic described at the top of this answer)
With the above code, you can intercept any PDF file on http and https URLs.
If you want to view PDF files from the local filesystem and/or ftp, then you need to use the chrome.webRequest.onBeforeRequest event instead of onHeadersReceived. Fortunately, you can assume that if the file ends with ".pdf", then the resource is most likely a PDF file. Users who want to use the extension to view a local PDF file have to explicitly allow this at the extension settings page though.
On Chrome OS, use the chrome.fileBrowserHandler API to register your extension as a PDF Viewer (https://github.com/mozilla/pdf.js/blob/master/extensions/chromium/pdfHandler-vcros.js).
The methods based on the webRequest API only work for PDFs in top-level documents and frames, not for PDFs embedded via <object> and <embed>. Although they are rare, I still wanted to support them, so I came up with an unconventional method to detect and load the PDF viewer in these contexts. The implementation can be viewed at https://github.com/mozilla/pdf.js/pull/4549/files. This method relies on the fact that when an element is put in the document, it eventually have to be rendered. When it is rendered, CSS styles get applied. When I declare an animation for the embed/object elements in the CSS, animation events will be triggered. These events bubble up in the document. I can then add a listener for this event, and replace the content of the object/embed element with an iframe that loads my PDF Viewer.
There are several ways to replace an element or content, but I've used Shadow DOM to change the displayed content without affecting the DOM in the page.
Limitations and notes
The method described here has a few limitations:
The PDF file is requested at least two times from the server: First a usual request to get the headers, which gets aborted when the extension redirects to the PDF Viewer. Then another request to request the actual data.
Consequently, if a file is valid only once, then the PDF cannot be displayed (the first request invalidates the URL and the second request fails).
This method only works for GET requests. There is no public API to directly get response bodies from a request in a Chrome extension (crbug.com/104058).
The method to get PDFs to work for <object> and <embed> elements requires a script to run on every page. I've profiled the code and found that the impact on performance is negligible, but you still need to be careful if you want to change the logic.
(I first tried to use Mutation Observers for detection, which slowed down the page load by 3-20% on huge documents, and caused an additional 1.5 GB peak in memory usage in a complex DOM benchmark).
The method to detect <object> / <embed> tags might still cause any NPAPI/PPAPI-based PDF plugins to load, because it only replaced the <embed>/<object> tag's content when it has already been inserted and rendered. When a tab is inactive, animations are not scheduled, and hence the dispatch of the animation event will significantly be delayed.
Afterword
PDF.js is open-source, you can view the code for the Chrome extension at https://github.com/mozilla/pdf.js/tree/master/extensions/chromium. If you browse the source, you'll notice that the code is a bit more complex than I explained here. That's because extensions cannot redirect requests at the onHeadersReceived event until I implemented it a few months ago (crbug.com/280464, Chrome 35).
And there is also some logic to make the URL in the omnibox look a bit better.
The PDF.js extension continues to evolve, so unless you want to significantly change the UI of the PDF Viewer, I suggest to ask users to install the PDF.js's official PDF Viewer in the Chrome Web Store, and/or open issues on PDF.js's issue tracker for reasonable feature requests.
Custom PDF Viewer
Basically, to accomplish what you want to do you'll need to:
Interject the PDF's URL when it's loaded;
Stop the PDF from loading;
Start your own PDF viewer and load the PDF inside it.
How to
Using the chrome.webRequest API you can easily listen to the web requests made by Chrome, and, more specifically, the ones that are going to load .pdf files. Using the chrome.webRequest.onBeforeRequest event you can listen to all the requests that end with ".pdf" and get the URL of the requested resource.
Create a page, for example display_pdf.html where you will show the PDFs and do whatever you want with them.
In the chrome.webRequest.onBeforeRequest listener, prevent the resource from being loaded returning {redirectUrl: ...} to redirect to your display_pdf.html page.
Pass the PDF's URL to your page. This can be done in several ways, but, for me, the simplest one is to add the encoded PDF URL at the end of your page's url, like an encoded query string, something like display_pdf.html?url=http%3A%2F%2Fwww.example.com%2Fexample.pdf.
Inside the page, get the URL with JavaScript and process and render the PDF with any library you want, like PDF.js.
The code
Following the above steps, your extension will look like this:
<root>/
/background.js
/display_pdf.html
/display_pdf.js
/manifest.json
So, first of all, let's look at the manifest.json file: you will need to declare the permissions for webRequest and webRequestBlocking, so it should look like this:
{
"manifest_version": 2,
"name": "PDF Test",
"version": "0.0.1",
"background": {
"scripts": ["/background.js"]
},
"permissions": ["webRequest", "webRequestBlocking", "<all_urls>"],
}
Then, in your background.js you will listen to the chrome.webRequest.onBeforeRequest event and update the tab which is loading the PDF with the URL of your custom display_pdv.html page, like this:
chrome.webRequest.onBeforeRequest.addListener(function(details) {
var displayURL;
if (/\.pdf$/i.test(details.url)) { // if the resource is a PDF file ends with ".pdf"
displayURL = chrome.runtime.getURL('/display_pdf.html') + '?url=' + encodeURIComponent(details.url);
return {redirectUrl: displayURL};
// stop the request and proceed to your custom display page
}
}, {urls: ['*://*/*.pdf']}, ['blocking']);
And finally, in your display_pdf.js file you will extract the PDF's url from the query string and use it to do whatever you want:
var PDF_URL = decodeURIComponent(location.href.split('?url=')[1]);
// this will be something like http://www.somesite.com/path/to/example.pdf
alert('The PDF url is: ' + PDF_URL);
// do something with the pdf... like processing it with PDF.js
Working Example
A working example of what I said above can be found HERE.
Documentation links
I recommend you to take a look at the official documentation of the above specified APIs, that you can find following these links:
chrome.webRequest API
chrome.webRequest.onBeforeRequest event
chrome.runtime API
chrome.runtime.getURL method

Downloading a music file instead of playing it in the browser

I'm trying to make a downloader on my website which starts downloading the selected files but the problem is it is a music file which just opens up in a new window and starts playing it.
The script is (don't worry about the id part it is for the next part):
function downloadsong(id){
var url = ("/music/downloadablesongs/linkin-park/Minutes-to-Midnight/wake.mp3");
window.open(url,'Download')
}
If you can configure the server that hosts the files, you should be able to manipulate the HTTP headers to include a "Content-Disposition" header. This will prompt the user agent (browser) to save the file, rather than allow it to automatically detect/interpret the content.
The basic format is:
Content-Disposition: attachment; filename=$file_name.ext
It depends on the user's browser. Usually, plugins or built-in browser capabilities take over and play it instead of letting the browser download.
What you can do is to have the file carry no extension (ie. remove .mp3). That way, it won't be picked-up by plugins. The down side is additional work for the user, by having to add the extension manually.
Other way is simply use the download attribute. I think is the simplest way.
<a href="/music/downloadablesongs/linkin-park/Minutes-to-Midnight/wake.mp3" download>
See more here.

Javascript .pac file

Is there a way to get a browser to read a .pac file without having the user manually point the browser's automatic config file at the URL?
Are you talking about Proxy Autoconfiguration?
Basically you have to configure a host name such as wpad.example.com and put the file there named as wpad.dat
See here: http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol
If you are using Chrome then you can use the chrome switch --proxy-pac-url
For example:
Open cmd.exe as admin
Make sure to first navigate to the path of Chrome (1st line) in cmd
Notice also that I used another chrome switch which is unsafe-pac-url this will allow your pac file to work for HTTPS requests, because otherwise chrome will only apply our PAC file to HTTP requests only.

Categories

Resources