mirror of
https://github.com/silkimen/cordova-plugin-advanced-http.git
synced 2026-01-31 00:00:03 +08:00
feat: add ponyfills to support multipart requests on android webview versions < 50 and iOS versions < 13.2
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"editor.tabSize": 2
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
<js-module src="www/local-storage-store.js" name="local-storage-store"/>
|
<js-module src="www/local-storage-store.js" name="local-storage-store"/>
|
||||||
<js-module src="www/lodash.js" name="lodash"/>
|
<js-module src="www/lodash.js" name="lodash"/>
|
||||||
<js-module src="www/messages.js" name="messages"/>
|
<js-module src="www/messages.js" name="messages"/>
|
||||||
|
<js-module src="www/ponyfills.js" name="ponyfills"/>
|
||||||
<js-module src="www/public-interface.js" name="public-interface"/>
|
<js-module src="www/public-interface.js" name="public-interface"/>
|
||||||
<js-module src="www/umd-tough-cookie.js" name="tough-cookie"/>
|
<js-module src="www/umd-tough-cookie.js" name="tough-cookie"/>
|
||||||
<js-module src="www/url-util.js" name="url-util"/>
|
<js-module src="www/url-util.js" name="url-util"/>
|
||||||
|
|||||||
@@ -799,12 +799,12 @@ const tests = [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disabled: true,
|
|
||||||
description: 'should serialize FormData instance correctly when it contains string value',
|
description: 'should serialize FormData instance correctly when it contains string value',
|
||||||
expected: 'resolved: {"status": 200, ...',
|
expected: 'resolved: {"status": 200, ...',
|
||||||
before: helpers.setMultipartSerializer,
|
before: helpers.setMultipartSerializer,
|
||||||
func: function (resolve, reject) {
|
func: function (resolve, reject) {
|
||||||
var formData = new FormData();
|
var ponyfills = cordova.plugin.http.ponyfills;
|
||||||
|
var formData = new ponyfills.FormData();
|
||||||
formData.append('myString', 'This is a test!');
|
formData.append('myString', 'This is a test!');
|
||||||
|
|
||||||
var url = 'https://httpbin.org/anything';
|
var url = 'https://httpbin.org/anything';
|
||||||
@@ -818,13 +818,13 @@ const tests = [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disabled: true,
|
|
||||||
description: 'should serialize FormData instance correctly when it contains blob value',
|
description: 'should serialize FormData instance correctly when it contains blob value',
|
||||||
expected: 'resolved: {"status": 200, ...',
|
expected: 'resolved: {"status": 200, ...',
|
||||||
before: helpers.setMultipartSerializer,
|
before: helpers.setMultipartSerializer,
|
||||||
func: function (resolve, reject) {
|
func: function (resolve, reject) {
|
||||||
|
var ponyfills = cordova.plugin.http.ponyfills;
|
||||||
helpers.getWithXhr(function(blob) {
|
helpers.getWithXhr(function(blob) {
|
||||||
var formData = new FormData();
|
var formData = new ponyfills.FormData();
|
||||||
formData.append('CordovaLogo', blob);
|
formData.append('CordovaLogo', blob);
|
||||||
|
|
||||||
var url = 'https://httpbin.org/anything';
|
var url = 'https://httpbin.org/anything';
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ const configs = {
|
|||||||
},
|
},
|
||||||
localAndroidEmulator: {
|
localAndroidEmulator: {
|
||||||
platformName: 'Android',
|
platformName: 'Android',
|
||||||
platformVersion: '9',
|
platformVersion: '5',
|
||||||
automationName: 'XCUITest',
|
|
||||||
deviceName: 'Android Emulator',
|
deviceName: 'Android Emulator',
|
||||||
autoWebview: true,
|
autoWebview: true,
|
||||||
fullReset: true,
|
fullReset: true,
|
||||||
|
|||||||
104
test/js-specs.js
104
test/js-specs.js
@@ -529,7 +529,7 @@ describe('Common helpers', function () {
|
|||||||
const jsUtil = require('../www/js-util');
|
const jsUtil = require('../www/js-util');
|
||||||
const messages = require('../www/messages');
|
const messages = require('../www/messages');
|
||||||
const dependencyValidator = require('../www/dependency-validator')(mockWindow, null, messages);
|
const dependencyValidator = require('../www/dependency-validator')(mockWindow, null, messages);
|
||||||
const helpers = require('../www/helpers')(mockWindow, jsUtil, null, messages, base64, null, dependencyValidator);
|
const helpers = require('../www/helpers')(mockWindow, jsUtil, null, messages, base64, null, dependencyValidator, {});
|
||||||
|
|
||||||
const testString = 'Test String öäüß 👍😉';
|
const testString = 'Test String öäüß 👍😉';
|
||||||
const testStringBase64 = Buffer.from(testString).toString('base64');
|
const testStringBase64 = Buffer.from(testString).toString('base64');
|
||||||
@@ -540,11 +540,6 @@ describe('Common helpers', function () {
|
|||||||
(() => helpers.processData({}, 'utf8')).should.throw(messages.TYPE_MISMATCH_DATA);
|
(() => helpers.processData({}, 'utf8')).should.throw(messages.TYPE_MISMATCH_DATA);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws an error when needed Web API is not available', () => {
|
|
||||||
const helpers = require('../www/helpers')({}, jsUtil, null, messages, null, null);
|
|
||||||
(() => helpers.processData(null, 'multipart')).should.throw(`${messages.INSTANCE_TYPE_NOT_SUPPORTED} FormData`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws an error when given data does not match allowed instance types', () => {
|
it('throws an error when given data does not match allowed instance types', () => {
|
||||||
(() => helpers.processData('myString', 'multipart')).should.throw(messages.INSTANCE_TYPE_MISMATCH_DATA);
|
(() => helpers.processData('myString', 'multipart')).should.throw(messages.INSTANCE_TYPE_MISMATCH_DATA);
|
||||||
});
|
});
|
||||||
@@ -640,12 +635,12 @@ describe('Dependency Validator', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('checkFormDataApi()', function () {
|
describe('checkFormDataInstance()', function () {
|
||||||
it('throws an error if FormData.entries() API is not supported', function () {
|
it('throws an error if FormData.entries() is not supported on given instance', function () {
|
||||||
const console = new ConsoleMock();
|
const console = new ConsoleMock();
|
||||||
const validator = require('../www/dependency-validator')({ FormData: {}}, console, messages);
|
const validator = require('../www/dependency-validator')({ FormData: {}}, console, messages);
|
||||||
|
|
||||||
(() => validator.checkFormDataApi()).should.throw(messages.MISSING_FORMDATA_ENTRIES_API);
|
(() => validator.checkFormDataInstance({})).should.throw(messages.MISSING_FORMDATA_ENTRIES_API);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -658,3 +653,94 @@ describe('Dependency Validator', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Ponyfills', function () {
|
||||||
|
const mockWindow = {
|
||||||
|
Blob: BlobMock,
|
||||||
|
File: FileMock,
|
||||||
|
};
|
||||||
|
|
||||||
|
const init = require('../www/ponyfills');
|
||||||
|
init.debug = true;
|
||||||
|
const ponyfills = init(mockWindow);
|
||||||
|
|
||||||
|
describe('Iterator', function () {
|
||||||
|
it('exposes interface correctly', () => {
|
||||||
|
const iterator = new ponyfills.Iterator([]);
|
||||||
|
iterator.next.should.be.a('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('next()', function () {
|
||||||
|
it('returns iteration object correctly when list is empty', () => {
|
||||||
|
const iterator = new ponyfills.Iterator([]);
|
||||||
|
iterator.next().should.be.eql({ done: true, value: undefined });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns iteration object correctly when end posititon of list is not reached yet', () => {
|
||||||
|
const iterator = new ponyfills.Iterator([['first', 'this is the first item']]);
|
||||||
|
iterator.next().should.be.eql({ done: false, value: ['first', 'this is the first item'] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns iteration object correctly when end posititon of list is already reached', () => {
|
||||||
|
const iterator = new ponyfills.Iterator([['first', 'this is the first item']]);
|
||||||
|
iterator.next();
|
||||||
|
iterator.next().should.be.eql({ done: true, value: undefined });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('FormData', function () {
|
||||||
|
it('exposes interface correctly', () => {
|
||||||
|
const formData = new ponyfills.FormData();
|
||||||
|
|
||||||
|
formData.append.should.be.a('function');
|
||||||
|
formData.entries.should.be.a('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('append()', function () {
|
||||||
|
it('appends string value correctly', () => {
|
||||||
|
const formData = new ponyfills.FormData();
|
||||||
|
|
||||||
|
formData.append('test', 'myTestString');
|
||||||
|
formData.__items[0].should.be.eql(['test', 'myTestString']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('appends numeric value correctly', () => {
|
||||||
|
const formData = new ponyfills.FormData();
|
||||||
|
|
||||||
|
formData.append('test', 10);
|
||||||
|
formData.__items[0].should.be.eql(['test', '10']);
|
||||||
|
formData.__items[0][1].should.be.a('string');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('appends Blob value correctly', () => {
|
||||||
|
const formData = new ponyfills.FormData();
|
||||||
|
const blob = new BlobMock(['another test'], { type: 'text/plain' });
|
||||||
|
|
||||||
|
formData.append('myBlob', blob, 'myFileName.txt');
|
||||||
|
formData.__items[0].should.be.eql(['myBlob', blob]);
|
||||||
|
formData.__items[0][1].name.should.be.equal('myFileName.txt');
|
||||||
|
formData.__items[0][1].lastModifiedDate.should.be.a('Date');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('appends File value correctly', () => {
|
||||||
|
const formData = new ponyfills.FormData();
|
||||||
|
const blob = new BlobMock(['another test'], { type: 'text/plain' });
|
||||||
|
const file = new FileMock(blob, 'myFileName.txt');
|
||||||
|
|
||||||
|
formData.append('myFile', file, 'myOverriddenFileName.txt');
|
||||||
|
formData.__items[0].should.be.eql(['myFile', file]);
|
||||||
|
formData.__items[0][1].name.should.be.equal('myFileName.txt');
|
||||||
|
formData.__items[0][1].lastModifiedDate.should.be.eql(file.lastModifiedDate);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('entries()', function () {
|
||||||
|
it('returns an iterator correctly', () => {
|
||||||
|
const formData = new ponyfills.FormData();
|
||||||
|
|
||||||
|
formData.entries().should.be.an.instanceof(ponyfills.Iterator);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -4,9 +4,14 @@ module.exports = class FileMock extends BlobMock {
|
|||||||
constructor(blob, fileName) {
|
constructor(blob, fileName) {
|
||||||
super(blob, { type: blob.type });
|
super(blob, { type: blob.type });
|
||||||
this._fileName = fileName || '';
|
this._fileName = fileName || '';
|
||||||
|
this.__lastModifiedDate = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return this._fileName;
|
return this._fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get lastModifiedDate() {
|
||||||
|
return this.__lastModifiedDate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ var lodash = require(pluginId + '.lodash');
|
|||||||
var WebStorageCookieStore = require(pluginId + '.local-storage-store')(ToughCookie, lodash);
|
var WebStorageCookieStore = require(pluginId + '.local-storage-store')(ToughCookie, lodash);
|
||||||
var cookieHandler = require(pluginId + '.cookie-handler')(window.localStorage, ToughCookie, WebStorageCookieStore);
|
var cookieHandler = require(pluginId + '.cookie-handler')(window.localStorage, ToughCookie, WebStorageCookieStore);
|
||||||
var dependencyValidator = require(pluginId + '.dependency-validator')(window, window.console, messages);
|
var dependencyValidator = require(pluginId + '.dependency-validator')(window, window.console, messages);
|
||||||
var helpers = require(pluginId + '.helpers')(window, jsUtil, cookieHandler, messages, base64, errorCodes, dependencyValidator);
|
var ponyfills = require(pluginId + '.ponyfills')(window);
|
||||||
|
var helpers = require(pluginId + '.helpers')(window, jsUtil, cookieHandler, messages, base64, errorCodes, dependencyValidator, ponyfills);
|
||||||
var urlUtil = require(pluginId + '.url-util')(jsUtil);
|
var urlUtil = require(pluginId + '.url-util')(jsUtil);
|
||||||
var publicInterface = require(pluginId + '.public-interface')(exec, cookieHandler, urlUtil, helpers, globalConfigs, errorCodes);
|
var publicInterface = require(pluginId + '.public-interface')(exec, cookieHandler, urlUtil, helpers, globalConfigs, errorCodes, ponyfills);
|
||||||
|
|
||||||
dependencyValidator.logWarnings();
|
dependencyValidator.logWarnings();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ module.exports = function init(global, console, messages) {
|
|||||||
var interface = {
|
var interface = {
|
||||||
checkBlobApi: checkBlobApi,
|
checkBlobApi: checkBlobApi,
|
||||||
checkFileReaderApi: checkFileReaderApi,
|
checkFileReaderApi: checkFileReaderApi,
|
||||||
checkFormDataApi: checkFormDataApi,
|
checkFormDataInstance: checkFormDataInstance,
|
||||||
checkTextEncoderApi: checkTextEncoderApi,
|
checkTextEncoderApi: checkTextEncoderApi,
|
||||||
logWarnings: logWarnings,
|
logWarnings: logWarnings,
|
||||||
};
|
};
|
||||||
@@ -29,8 +29,8 @@ module.exports = function init(global, console, messages) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFormDataApi() {
|
function checkFormDataInstance(instance) {
|
||||||
if (!global.FormData || !global.FormData.prototype || !global.FormData.prototype.entries) {
|
if (!instance || !instance.entries) {
|
||||||
throw new Error(messages.MISSING_FORMDATA_ENTRIES_API);
|
throw new Error(messages.MISSING_FORMDATA_ENTRIES_API);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = function init(global, jsUtil, cookieHandler, messages, base64, errorCodes, dependencyValidator) {
|
module.exports = function init(global, jsUtil, cookieHandler, messages, base64, errorCodes, dependencyValidator, ponyfills) {
|
||||||
var validSerializers = ['urlencoded', 'json', 'utf8', 'multipart'];
|
var validSerializers = ['urlencoded', 'json', 'utf8', 'multipart'];
|
||||||
var validCertModes = ['default', 'nocheck', 'pinned', 'legacy'];
|
var validCertModes = ['default', 'nocheck', 'pinned', 'legacy'];
|
||||||
var validClientAuthModes = ['none', 'systemstore', 'buffer'];
|
var validClientAuthModes = ['none', 'systemstore', 'buffer'];
|
||||||
@@ -370,24 +370,30 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllowedInstanceType(dataSerializer) {
|
function getAllowedInstanceTypes(dataSerializer) {
|
||||||
return dataSerializer === 'multipart' ? 'FormData' : null;
|
return dataSerializer === 'multipart' ? ['FormData'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function processData(data, dataSerializer, cb) {
|
function processData(data, dataSerializer, cb) {
|
||||||
var currentDataType = jsUtil.getTypeOf(data);
|
var currentDataType = jsUtil.getTypeOf(data);
|
||||||
var allowedDataTypes = getAllowedDataTypes(dataSerializer);
|
var allowedDataTypes = getAllowedDataTypes(dataSerializer);
|
||||||
var allowedInstanceType = getAllowedInstanceType(dataSerializer);
|
var allowedInstanceTypes = getAllowedInstanceTypes(dataSerializer);
|
||||||
|
|
||||||
if (allowedInstanceType && !global[allowedInstanceType]) {
|
if (allowedInstanceTypes) {
|
||||||
throw new Error(messages.INSTANCE_TYPE_NOT_SUPPORTED + ' ' + allowedInstanceType);
|
var isCorrectInstanceType = false;
|
||||||
|
|
||||||
|
allowedInstanceTypes.forEach(function(type) {
|
||||||
|
if ((global[type] && data instanceof global[type]) || (ponyfills[type] && data instanceof ponyfills[type])) {
|
||||||
|
isCorrectInstanceType = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isCorrectInstanceType) {
|
||||||
|
throw new Error(messages.INSTANCE_TYPE_MISMATCH_DATA + ' ' + allowedInstanceTypes.join(', '));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowedInstanceType && !(data instanceof global[allowedInstanceType])) {
|
if (!allowedInstanceTypes && allowedDataTypes.indexOf(currentDataType) === -1) {
|
||||||
throw new Error(messages.INSTANCE_TYPE_MISMATCH_DATA + ' ' + allowedInstanceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allowedInstanceType && allowedDataTypes.indexOf(currentDataType) === -1) {
|
|
||||||
throw new Error(messages.TYPE_MISMATCH_DATA + ' ' + allowedDataTypes.join(', '));
|
throw new Error(messages.TYPE_MISMATCH_DATA + ' ' + allowedDataTypes.join(', '));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,8 +410,8 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
|
|||||||
function processFormData(data, cb) {
|
function processFormData(data, cb) {
|
||||||
dependencyValidator.checkBlobApi();
|
dependencyValidator.checkBlobApi();
|
||||||
dependencyValidator.checkFileReaderApi();
|
dependencyValidator.checkFileReaderApi();
|
||||||
dependencyValidator.checkFormDataApi();
|
|
||||||
dependencyValidator.checkTextEncoderApi();
|
dependencyValidator.checkTextEncoderApi();
|
||||||
|
dependencyValidator.checkFormDataInstance(data);
|
||||||
|
|
||||||
var textEncoder = new global.TextEncoder('utf8');
|
var textEncoder = new global.TextEncoder('utf8');
|
||||||
var iterator = data.entries();
|
var iterator = data.entries();
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ module.exports = {
|
|||||||
EMPTY_FILE_PATHS: 'advanced-http: "filePaths" option array must not be empty, <filePaths: string[]>',
|
EMPTY_FILE_PATHS: 'advanced-http: "filePaths" option array must not be empty, <filePaths: string[]>',
|
||||||
EMPTY_NAMES: 'advanced-http: "names" option array must not be empty, <names: string[]>',
|
EMPTY_NAMES: 'advanced-http: "names" option array must not be empty, <names: string[]>',
|
||||||
INSTANCE_TYPE_MISMATCH_DATA: 'advanced-http: "data" option is configured to support only following instance types:',
|
INSTANCE_TYPE_MISMATCH_DATA: 'advanced-http: "data" option is configured to support only following instance types:',
|
||||||
INSTANCE_TYPE_NOT_SUPPORTED: 'advanced-http: this webview does not support following Web API which is needed for this plugin:',
|
|
||||||
INVALID_CLIENT_AUTH_ALIAS: 'advanced-http: invalid client certificate alias, needs to be a string or undefined, <alias: string | undefined>',
|
INVALID_CLIENT_AUTH_ALIAS: 'advanced-http: invalid client certificate alias, needs to be a string or undefined, <alias: string | undefined>',
|
||||||
INVALID_CLIENT_AUTH_MODE: 'advanced-http: invalid client certificate authentication mode, supported modes are:',
|
INVALID_CLIENT_AUTH_MODE: 'advanced-http: invalid client certificate authentication mode, supported modes are:',
|
||||||
INVALID_CLIENT_AUTH_OPTIONS: 'advanced-http: invalid client certificate authentication options, needs to be an dictionary style object',
|
INVALID_CLIENT_AUTH_OPTIONS: 'advanced-http: invalid client certificate authentication options, needs to be an dictionary style object',
|
||||||
@@ -22,7 +21,7 @@ module.exports = {
|
|||||||
MISSING_BLOB_API: 'advanced-http: Blob API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
MISSING_BLOB_API: 'advanced-http: Blob API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
||||||
MISSING_FILE_READER_API: 'advanced-http: FileReader API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
MISSING_FILE_READER_API: 'advanced-http: FileReader API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
||||||
MISSING_FORMDATA_API: 'advanced-http: FormData API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
MISSING_FORMDATA_API: 'advanced-http: FormData API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
||||||
MISSING_FORMDATA_ENTRIES_API: 'advanced-http: This webview does not implement FormData API specification correctly, FormData.entries() is missing. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
MISSING_FORMDATA_ENTRIES_API: 'advanced-http: Given instance of FormData does not implement FormData API specification correctly, FormData.entries() is missing. If you want to use "multipart/form-data" requests, you can use an included ponyfill. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
||||||
MISSING_TEXT_ENCODER_API: 'advanced-http: TextEncoder API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
MISSING_TEXT_ENCODER_API: 'advanced-http: TextEncoder API is not supported in this webview. If you want to use "multipart/form-data" requests, you need to load a polyfill library before loading this plugin. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info.',
|
||||||
POST_PROCESSING_FAILED: 'advanced-http: an error occured during post processing response:',
|
POST_PROCESSING_FAILED: 'advanced-http: an error occured during post processing response:',
|
||||||
TYPE_MISMATCH_DATA: 'advanced-http: "data" option is configured to support only following data types:',
|
TYPE_MISMATCH_DATA: 'advanced-http: "data" option is configured to support only following data types:',
|
||||||
|
|||||||
47
www/ponyfills.js
Normal file
47
www/ponyfills.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
module.exports = function init(global) {
|
||||||
|
var interface = { FormData: FormData };
|
||||||
|
|
||||||
|
// expose all constructor functions for testing purposes
|
||||||
|
if (init.debug) {
|
||||||
|
interface.Iterator = Iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
function FormData() {
|
||||||
|
this.__items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
FormData.prototype.append = function(name, value, filename) {
|
||||||
|
if (global.File && value instanceof global.File) {
|
||||||
|
// nothing to do
|
||||||
|
} else if (global.Blob && value instanceof global.Blob) {
|
||||||
|
// mimic File instance by adding missing properties
|
||||||
|
value.lastModifiedDate = new Date();
|
||||||
|
value.name = filename || '';
|
||||||
|
} else {
|
||||||
|
value = value.toString ? value.toString() : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.__items.push([ name, value ]);
|
||||||
|
};
|
||||||
|
|
||||||
|
FormData.prototype.entries = function() {
|
||||||
|
return new Iterator(this.__items);
|
||||||
|
};
|
||||||
|
|
||||||
|
function Iterator(items) {
|
||||||
|
this.__items = items;
|
||||||
|
this.__position = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator.prototype.next = function() {
|
||||||
|
this.__position += 1;
|
||||||
|
|
||||||
|
if (this.__position < this.__items.length) {
|
||||||
|
return { done: false, value: this.__items[this.__position] };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { done: true, value: undefined };
|
||||||
|
}
|
||||||
|
|
||||||
|
return interface;
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConfigs, errorCodes) {
|
module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConfigs, errorCodes, ponyfills) {
|
||||||
var publicInterface = {
|
var publicInterface = {
|
||||||
getBasicAuthHeader: getBasicAuthHeader,
|
getBasicAuthHeader: getBasicAuthHeader,
|
||||||
useBasicAuth: useBasicAuth,
|
useBasicAuth: useBasicAuth,
|
||||||
@@ -29,7 +29,8 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf
|
|||||||
head: head,
|
head: head,
|
||||||
uploadFile: uploadFile,
|
uploadFile: uploadFile,
|
||||||
downloadFile: downloadFile,
|
downloadFile: downloadFile,
|
||||||
ErrorCode: errorCodes
|
ErrorCode: errorCodes,
|
||||||
|
ponyfills: ponyfills
|
||||||
};
|
};
|
||||||
|
|
||||||
function getBasicAuthHeader(username, password) {
|
function getBasicAuthHeader(username, password) {
|
||||||
|
|||||||
Reference in New Issue
Block a user