We have an app using Phonegap 3.6.3 and built with Phonegap build.
As part of this app, we need to download a file onto the device of the user. The file might be a .pdf, an image or any binary file.
We hope to download the file with a blob:file link in the app, and not use a plugin such as file-transfer.
The file is converted from Base64 data and a Blob object is created.
An objectURL is generated through window.URL.createObjectURL() and this is added to the href attribute of an a element.
The DOM contains the following
<a href="blob:file%3A///cf2e336c-8c10-4e54-9e99-26f7d5a0115f" download="1.jpg" style="display: none;"></a>
On desktop, this works without problems, but in the app packaged with cordova 3.6.3 it just fails silently.
I suspect it's related to whitelist functionality in cordova.
In the question https://stackoverflow.com/a/31945728/250787 others have solved the same problem with the cordova-plugin-whitelist.
Unfortunately, this plugin is only for cordova 4.0+
I've tried using the access origin element, but none of the statements appears to have an effect
<access origin="blob:*" launch-external="yes" />
<access origin="blob:*"/>
I already have a access origin to limit traffic to the main backend system of the app
<access origin="https://mobilbackend.mycompany.com/*"/>
How can this be solved?
Okay. blob:
requires special additions to the whitelist
system, of which you seem to have an incomplete understanding _OR_ are using outdated documentation. I can tell because launch-external="yes"
has been removed from use.
- You will need to use both the
whitelist
plugin and add a <meta (...) />
entry into the header of our .html
pages.
- You need to implement the cordova-plugin-whitelist.
- This whitelist worksheet should help.
HOW TO apply the Cordova/Phonegap the whitelist system
NOTE DOING THIS WILL MAKE YOUR APP INSECURE. IT IS UP TO YOU TO SECURE YOUR APP.
Add this to your config.xml
<plugin name="cordova-plugin-whitelist" source="npm" spec="1.1.0" />
<allow-navigation href="*" />
<allow-intent href="*" />
<access origin="*" /> <!-- Required for iOS9 -->
NOTE YOUR APP IS NOW INSECURE. IT IS UP TO YOU TO SECURE YOUR APP.
Add the following to your index.html
and every .html
page.
<meta http-equiv="Content-Security-Policy"
content="default-src * blob:;
style-src * 'self' 'unsafe-inline' 'unsafe-eval';
script-src * 'self' 'unsafe-inline' 'unsafe-eval';">
I have added blob:
into the CSP
definition. However, this just opens up the app to allow the blob:
URL. It is still not clear to me what you mean when you say "download the file", as blob:
is not transport protocol. It is only intended to define a type of file.
I also recommend reading this whitelist worksheet, make sure to read 9. CSP (Content Security Policy)
Lastly, if you want to continue this discussion, please continue on Google Groups
So I created a solution that saves the blob and then opens it with the system viewer.
If you want it to be saved in a different location see: here.
By choosing this location you can have it download straight to the desired location.
If you open the file with the system viewer then there is often an option for the user to save the file.
// previously blob is defined as file,
//and file name is saved in data.FileName
var savedFile;
window.resolveLocalFileSystemURL( cordova.file.cacheDirectory, function( dir ) {
dir.getFile( data.FileName, { create:true }, function( file_ ) {
savedFile = file_;
saveFile();
});
});
function saveFile(str) {
if( !savedFile ) return;
savedFile.createWriter(function(fileWriter) {
fileWriter.write( file );
cordova.plugins.disusered.open( savedFile.nativeURL );
console.log( "file " + savedFile.nativeURL + " opened" );
}, function( e ){
throw( 'createWriter Error error' + JSON.stringify( e ) );
});
}
This uses the plugins of:
cordova plugin add cordova-plugin-file --save
cordova plugin add cordova-open --save