FileTransfer.prototype.download = function()

in www/browser/FileTransfer.js [231:348]


FileTransfer.prototype.download = function (source, target, successCallback, errorCallback, trustAllHosts, options) {
    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);

    // Check if target URL doesn't contain spaces. If contains, it should be escaped first
    // (see https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md#download)
    if (!checkURL(source)) {
        if (errorCallback) {
            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target));
        }
        return;
    }

    options = options || {};

    const headers = options.headers || {};
    const withCredentials = options.withCredentials || false;

    const basicAuthHeader = getBasicAuthHeader(source);
    if (basicAuthHeader) {
        source = source.replace(getUrlCredentials(source) + '@', '');
        headers[basicAuthHeader.name] = basicAuthHeader.value;
    }

    const that = this;
    const xhr = (transfers[this._id] = new XMLHttpRequest());
    xhr.withCredentials = withCredentials;
    const fail =
        errorCallback &&
        function (code, status, response) {
            if (transfers[that._id]) {
                delete transfers[that._id];
            }
            // In XHR GET reqests we're setting response type to Blob
            // but in case of error we need to raise event with plain text response
            if (response instanceof Blob) {
                const reader = new FileReader();
                reader.readAsText(response);
                reader.onloadend = function (e) {
                    const error = new FileTransferError(code, source, target, status, e.target.result);
                    errorCallback(error);
                };
            } else {
                const error = new FileTransferError(code, source, target, status, response);
                errorCallback(error);
            }
        };

    xhr.onload = function (e) {
        const fileNotFound = function () {
            fail(FileTransferError.FILE_NOT_FOUND_ERR);
        };

        const req = e.target;
        // req.status === 0 is special case for local files with file:// URI scheme
        if ((req.status === 200 || req.status === 0) && req.response) {
            window.resolveLocalFileSystemURL(
                getParentPath(target),
                function (dir) {
                    dir.getFile(
                        getFileName(target),
                        { create: true },
                        function writeFile (entry) {
                            entry.createWriter(function (fileWriter) {
                                fileWriter.onwriteend = function (evt) {
                                    if (!evt.target.error) {
                                        entry.filesystemName = entry.filesystem.name;
                                        delete transfers[that._id];
                                        if (successCallback) {
                                            successCallback(entry);
                                        }
                                    } else {
                                        fail(FileTransferError.FILE_NOT_FOUND_ERR);
                                    }
                                };
                                fileWriter.onerror = function () {
                                    fail(FileTransferError.FILE_NOT_FOUND_ERR);
                                };
                                fileWriter.write(req.response);
                            }, fileNotFound);
                        },
                        fileNotFound
                    );
                },
                fileNotFound
            );
        } else if (req.status === 404) {
            fail(FileTransferError.INVALID_URL_ERR, req.status, req.response);
        } else {
            fail(FileTransferError.CONNECTION_ERR, req.status, req.response);
        }
    };

    xhr.onprogress = function (e) {
        if (that.onprogress) {
            that.onprogress(e);
        }
    };

    xhr.onerror = function () {
        fail(FileTransferError.CONNECTION_ERR, this.status, this.response);
    };

    xhr.onabort = function () {
        fail(FileTransferError.ABORT_ERR, this.status, this.response);
    };

    xhr.open('GET', source, true);

    for (const header in headers) {
        if (Object.prototype.hasOwnProperty.call(headers, header)) {
            xhr.setRequestHeader(header, headers[header]);
        }
    }

    xhr.responseType = 'blob';

    xhr.send();
};