Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
---
title: File Transfer
description: Upload and download files.
---
<!--
# license: Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-->
|AppVeyor|Travis CI|
|:-:|:-:|
|[](https://ci.appveyor.com/project/ApacheSoftwareFoundation/cordova-plugin-file-transfer)|[](https://travis-ci.org/apache/cordova-plugin-file-transfer)|
# cordova-plugin-file-transfer
This plugin allows you to upload and download files.
This plugin defines global `FileTransfer`, `FileUploadOptions` constructors. Although in the global scope, they are not available until after the `deviceready` event.
```js
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log(FileTransfer);
}
```
> To get a few ideas, check out the [sample](#sample) at the bottom of this page.
Report issues with this plugin on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20File%20Transfer%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)
## Deprecated
With the new features introduced in [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), this plugin is not needed any more. Migrating from this plugin to using the new features of [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), is explained in this [Cordova blog post](https://cordova.apache.org/blog/2017/10/18/from-filetransfer-to-xhr2.html).
## Installation
```bash
cordova plugin add cordova-plugin-file-transfer
```
## Supported Platforms
- Amazon Fire OS
- Android
- BlackBerry 10
- Browser
- Firefox OS**
- iOS
- Windows Phone 7 and 8*
- Windows
\* _Do not support `onprogress` nor `abort()`_
\** _Do not support `onprogress`_
# FileTransfer
The `FileTransfer` object provides a way to upload files using an HTTP
multi-part POST or PUT request, and to download files.
## Properties
- __onprogress__: Called with a `ProgressEvent` whenever a new chunk of data is transferred. _(Function)_
## Methods
- __upload__: Sends a file to a server.
- __download__: Downloads a file from server.
- __abort__: Aborts an in-progress transfer.
## upload
__Parameters__:
- __fileURL__: Filesystem URL representing the file on the device or a [data URI](https://en.wikipedia.org/wiki/Data_URI_scheme). For backwards compatibility, this can also be the full path of the file on the device. (See [Backwards Compatibility Notes](#backwards-compatibility-notes) below)
- __server__: URL of the server to receive the file, as encoded by `encodeURI()`.
- __successCallback__: A callback that is passed a `FileUploadResult` object. _(Function)_
- __errorCallback__: A callback that executes if an error occurs retrieving the `FileUploadResult`. Invoked with a `FileTransferError` object. _(Function)_
- __options__: Optional parameters _(Object)_. Valid keys:
- __fileKey__: The name of the form element. Defaults to `file`. (DOMString)
- __fileName__: The file name to use when saving the file on the server. Defaults to `image.jpg`. (DOMString)
- __httpMethod__: The HTTP method to use - either `PUT` or `POST`. Defaults to `POST`. (DOMString)
- __mimeType__: The mime type of the data to upload. Defaults to `image/jpeg`. (DOMString)
- __params__: A set of optional key/value pairs to pass in the HTTP request. (Object, key/value - DOMString)
- __chunkedMode__: Whether to upload the data in chunked streaming mode. Defaults to `true`. (Boolean)
- __headers__: A map of header name/header values. Use a hash to specify one or more than one value. On iOS, FireOS, and Android, if a header named Content-Type is present, multipart form data will NOT be used. (Object)
- __trustAllHosts__: Optional parameter, defaults to `false`. If set to `true`, it accepts all security certificates. Not recommended for production use. Supported on iOS. _(boolean)_
### Example
```js
// !! Assumes variable fileURL contains a valid URL to a text file on the device,
// for example, cdvfile://localhost/persistent/path/to/file.txt
var win = function (r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
var fail = function (error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
options.mimeType = "text/plain";
var params = {};
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(fileURL, encodeURI("http://some.server.com/upload.php"), win, fail, options);
```
### Example with Upload Headers and Progress Events (Android and iOS only)
```js
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var uri = encodeURI("http://some.server.com/upload.php");
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);
options.mimeType="text/plain";
var headers={'headerParam':'headerValue', 'headerParam2':'headerValue2'};
options.headers = headers;
var ft = new FileTransfer();
ft.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
} else {
loadingStatus.increment();
}
};
ft.upload(fileURL, uri, win, fail, options);
```
## FileUploadResult
A `FileUploadResult` object is passed to the success callback of the
`FileTransfer` object's `upload()` method.
### Properties
- __bytesSent__: The number of bytes sent to the server as part of the upload. (long)
- __responseCode__: The HTTP response code returned by the server. (long)
- __response__: The HTTP response returned by the server. (DOMString)
- __headers__: The HTTP response headers by the server. (Object)
- Currently supported on iOS only.
### iOS Quirks
- Does not support `responseCode` or `bytesSent`.
- Does not support uploads of an empty file with __chunkedMode=true__ and `multipartMode=false`.
### Browser Quirks
- __withCredentials__: _boolean_ that tells the browser to set the withCredentials flag on the XMLHttpRequest
### Windows Quirks
- An option parameter with empty/null value is excluded in the upload operation due to the Windows API design.
- __chunkedMode__ is not supported and all uploads are set to non-chunked mode.
## download
__Parameters__:
- __source__: URL of the server to download the file, as encoded by `encodeURI()`.
- __target__: Filesystem url representing the file on the device. For backwards compatibility, this can also be the full path of the file on the device. (See [Backwards Compatibility Notes](#backwards-compatibility-notes) below)
- __successCallback__: A callback that is passed a `FileEntry` object. _(Function)_
- __errorCallback__: A callback that executes if an error occurs when retrieving the `FileEntry`. Invoked with a `FileTransferError` object. _(Function)_
- __trustAllHosts__: Optional parameter, defaults to `false`. If set to `true`, it accepts all security certificates. Not recommended for production use. Supported on iOS. _(boolean)_
- __options__: Optional parameters, currently only supports headers (such as Authorization (Basic Authentication), etc).
### Example
```js
// !! Assumes variable fileURL contains a valid URL to a path on the device,
// for example, cdvfile://localhost/persistent/path/to/downloads/
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");
fileTransfer.download(
uri,
fileURL,
function(entry) {
console.log("download complete: " + entry.toURL());
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("download error code" + error.code);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
```
### WP8 Quirks
- Download requests is being cached by native implementation. To avoid caching, pass `if-Modified-Since` header to download method.
### Browser Quirks
- __withCredentials__: _boolean_ that tells the browser to set the withCredentials flag on the XMLHttpRequest
## abort
Aborts an in-progress transfer. The onerror callback is passed a FileTransferError object which has an error code of `FileTransferError.ABORT_ERR`.
### Example
```js
// !! Assumes variable fileURL contains a valid URL to a text file on the device,
// for example, cdvfile://localhost/persistent/path/to/file.txt
var win = function(r) {
console.log("Should not be called.");
}
var fail = function(error) {
// error.code == FileTransferError.ABORT_ERR
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName="myphoto.jpg";
options.mimeType="image/jpeg";
var ft = new FileTransfer();
ft.upload(fileURL, encodeURI("http://some.server.com/upload.php"), win, fail, options);
ft.abort();
```
## FileTransferError
A `FileTransferError` object is passed to an error callback when an error occurs.
### Properties
- __code__: One of the predefined error codes listed below. (Number)
- __source__: URL to the source. (String)
- __target__: URL to the target. (String)
- __http_status__: HTTP status code. This attribute is only available when a response code is received from the HTTP connection. (Number)
- __body__ Response body. This attribute is only available when a response is received from the HTTP connection. (String)
- __exception__: Either e.getMessage or e.toString (String)
### iOS Quirks
__exception__ is never defined.
### Constants
- 1 = `FileTransferError.FILE_NOT_FOUND_ERR`
- 2 = `FileTransferError.INVALID_URL_ERR`
- 3 = `FileTransferError.CONNECTION_ERR`
- 4 = `FileTransferError.ABORT_ERR`
- 5 = `FileTransferError.NOT_MODIFIED_ERR`
## Windows Quirks
- The plugin implementation is based on [BackgroundDownloader](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.backgrounddownloader.aspx)/[BackgroundUploader](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.backgrounduploader.aspx), which entails the latency issues on Windows devices (creation/starting of an operation can take up to a few seconds). You can use XHR or [HttpClient](https://msdn.microsoft.com/en-us/library/windows/apps/windows.web.http.httpclient.aspx) as a quicker alternative for small downloads.
## Backwards Compatibility Notes
Previous versions of this plugin would only accept device-absolute-file-paths as the source for uploads, or as the target for downloads. These paths would typically be of the form:
/var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS)
/storage/emulated/0/path/to/file (Android)
For backwards compatibility, these paths are still accepted, and if your application has recorded paths like these in persistent storage, then they can continue to be used.
These paths were previously exposed in the `fullPath` property of `FileEntry` and `DirectoryEntry` objects returned by the File plugin. New versions of the File plugin however, no longer expose these paths to JavaScript.
If you are upgrading to a new (1.0.0 or newer) version of File, and you have previously been using `entry.fullPath` as arguments to `download()` or `upload()`, then you will need to change your code to use filesystem URLs instead.
`FileEntry.toURL()` and `DirectoryEntry.toURL()` return a filesystem URL of the form:
cdvfile://localhost/persistent/path/to/file
which can be used in place of the absolute file path in both `download()` and `upload()` methods.
## Sample: Download and Upload Files <a name="sample"></a>
Use the File-Transfer plugin to upload and download files. In these examples, we demonstrate several tasks like:
* [Downloading a binary file to the application cache](#binaryFile)
* [Uploading a file created in your application's root](#uploadFile)
* [Downloading the uploaded file](#downloadFile)
## Download a Binary File to the application cache <a name="binaryFile"></a>
Use the File plugin with the File-Transfer plugin to provide a target for the files that you download (the target must be a FileEntry object). Before you download the file, create a DirectoryEntry object by using `resolveLocalFileSystemURL` and calling `fs.root` in the success callback. Use the `getFile` method of DirectoryEntry to create the target file.
```js
window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) {
console.log('file system open: ' + fs.name);
// Make sure you add the domain name to the Content-Security-Policy <meta> element.
var url = 'http://cordova.apache.org/static/img/cordova_bot.png';
// Parameters passed to getFile create a new file or return the file if it already exists.
fs.root.getFile('downloaded-image.png', { create: true, exclusive: false }, function (fileEntry) {
download(fileEntry, url, true);
}, onErrorCreateFile);
}, onErrorLoadFs);
```
>*Note* For persistent storage, pass LocalFileSystem.PERSISTENT to requestFileSystem.
When you have the FileEntry object, download the file using the `download` method of the FileTransfer object. The 3rd argument to the `download` function of FileTransfer is the success callback, which you can use to call the app's `readBinaryFile` function. In this code example, the `entry` variable is a new FileEntry object that receives the result of the download operation.
```js
function download(fileEntry, uri, readBinaryData) {
var fileTransfer = new FileTransfer();
var fileURL = fileEntry.toURL();
fileTransfer.download(
uri,
fileURL,
function (entry) {
console.log("Successful download...");
console.log("download complete: " + entry.toURL());
if (readBinaryData) {
// Read the file...
readBinaryFile(entry);
}
else {
// Or just display it.
displayImageByFileURL(entry);
}
},
function (error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
},
null, // or, pass false
{
//headers: {
// "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
//}
}
);
}
```
If you just need to display the image, take the FileEntry to call its toURL() function.
```js
function displayImageByFileURL(fileEntry) {
var elem = document.getElementById('imageElement');
elem.src = fileEntry.toURL();
}
```
Depending on your app requirements, you may want to read the file. To support operations with binary files, FileReader supports two methods, `readAsBinaryString` and `readAsArrayBuffer`. In this example, use `readAsArrayBuffer` and pass the FileEntry object to the method. Once you read the file successfully, construct a Blob object using the result of the read.
```js
function readBinaryFile(fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log("Successful file read: " + this.result);
// displayFileData(fileEntry.fullPath + ": " + this.result);
var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" });
displayImage(blob);
};
reader.readAsArrayBuffer(file);
}, onErrorReadFile);
}
```
Once you read the file successfully, you can create a DOM URL string using `createObjectURL`, and then display the image.
```js
function displayImage(blob) {
// Note: Use window.URL.revokeObjectURL when finished with image.
var objURL = window.URL.createObjectURL(blob);
// Displays image if result is a valid DOM string for an image.
var elem = document.getElementById('imageElement');
elem.src = objURL;
}
```
As you saw previously, you can call FileEntry.toURL() instead to just display the downloaded image (skip the file read).
## Upload a File <a name="uploadFile"></a>
When you upload a File using the File-Transfer plugin, use the File plugin to provide files for upload (again, they must be FileEntry objects). Before you can upload anything, create a file for upload using the `getFile` method of DirectoryEntry. In this example, create the file in the application's cache (fs.root). Then call the app's writeFile function so you have some content to upload.
```js
function onUploadFile() {
window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) {
console.log('file system open: ' + fs.name);
var fileName = "uploadSource.txt";
var dirEntry = fs.root;
dirEntry.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) {
// Write something to the file before uploading it.
writeFile(fileEntry);
}, onErrorCreateFile);
}, onErrorLoadFs);
}
```
In this example, create some simple content, and then call the app's upload function.
```js
function writeFile(fileEntry, dataObj) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function () {
console.log("Successful file write...");
upload(fileEntry);
};
fileWriter.onerror = function (e) {
console.log("Failed file write: " + e.toString());
};
if (!dataObj) {
dataObj = new Blob(['file data to upload'], { type: 'text/plain' });
}
fileWriter.write(dataObj);
});
}
```
Forward the FileEntry object to the upload function. To perform the actual upload, use the upload function of the FileTransfer object.
```js
function upload(fileEntry) {
// !! Assumes variable fileURL contains a valid URL to a text file on the device,
var fileURL = fileEntry.toURL();
var success = function (r) {
console.log("Successful upload...");
console.log("Code = " + r.responseCode);
// displayFileData(fileEntry.fullPath + " (content uploaded to server)");
}
var fail = function (error) {
alert("An error has occurred: Code = " + error.code);
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
options.mimeType = "text/plain";
var params = {};
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
// SERVER must be a URL that can handle the request, like
// http://some.server.com/upload.php
ft.upload(fileURL, encodeURI(SERVER), success, fail, options);
};
```
## Download the uploaded file <a name="downloadFile"></a>
To download the image you just uploaded, you will need a valid URL that can handle the request, for example, http://some.server.com/download.php. Again, the success handler for the FileTransfer.download method receives a FileEntry object. The main difference here from previous examples is that we call FileReader.readAsText to read the result of the download operation, because we uploaded a file with text content.
```js
function download(fileEntry, uri) {
var fileTransfer = new FileTransfer();
var fileURL = fileEntry.toURL();
fileTransfer.download(
uri,
fileURL,
function (entry) {
console.log("Successful download...");
console.log("download complete: " + entry.toURL());
readFile(entry);
},
function (error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
},
null, // or, pass false
{
//headers: {
// "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
//}
}
);
}
```
In the readFile function, call the `readAsText` method of the FileReader object.
```js
function readFile(fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function () {
console.log("Successful file read: " + this.result);
// displayFileData(fileEntry.fullPath + ": " + this.result);
};
reader.readAsText(file);
}, onErrorReadFile);
}
```