La mejor alternativa del plugin cordova-plugin-file-transfer para una aplicación Capacitor depende de una sola pregunta: ¿el transfer necesita sobrevivir a la aplicación que se va al fondo? @capacitor/file-transfer plugin. Para archivos grandes, redes inestables o transferencias que deben seguir adelante cuando el usuario cambia de aplicaciones, utilice @capgo/capacitor-uploader y @capgo/capacitor-downloaderque se ejecutan en APIs de transferencia de fondo nativas. Este guía los compara y mapea cada FileTransfer llamada.
¿El plugin cordova-plugin-file-transfer todavía está descontinuado?
La historia es confusa, así que aquí están los hechos:
- In 2017, el equipo de Apache Cordova anunció que planeaba deprecate el plugin y señaló a los desarrolladores a
XMLHttpRequestNivel 2. - El plugin nunca se marcó como deprecado en la versión npm. La versión 2.0.0 se lanzó en septiembre de 2023, y 2.0.1 en agosto de 2026. El repositorio GitHub es activo.
No está muerto. Pero en una aplicación Capacitor todavía es un plugin de Cordova que:
- depende de
cordova-plugin-filey suscdvfile://yfile://modelo de ruta - no se ajusta a Capacitor’s
Filesystemdirectórios y conversiónes de URI, - directorio y conversiones de URI de __CAPGO_KEEP_0__
- no tiene soporte de transferencia de fondo,
If estás migrando desde Cordova, reemplazarlo con plugins nativos Capacitor elimina uno de los últimos motivos para mantener cordova-plugin-file.
Por qué "solo usa fetch" falla con archivos grandes
La sugerencia de Apache para reemplazarlo, XHR, funciona para JSON y imágenes pequeñas. Falla para transferencias de archivos reales en una aplicación híbrida:
- Memoria.
fetchy XHR te dan unBloboArrayBufferin the WebView. A 500 MB video means 500 MB in WebView memory, then a copy to write it through the bridge. On mid-range Android devices that crashes the renderer. - Suspension. Cuando el usuario cambia de aplicación, iOS suspende la vista web. Las solicitudes en curso se bloquean o fallan.
- No integración del sistema operativo. No notificación de descarga del sistema, no opción de Wi-Fi solo, no reanudar después de una conexión interrumpida.
No notificación de descarga del sistema, no opción de Wi-Fi solo, no reanudar después de una conexión interrumpida.
Las opciones comparadas
| Necesita | cordova-plugin-file-transfer | @capacitor/file-transfer | @capgo/capacitor-uploader | @capgo/descargadorcapacitor |
|---|---|---|---|---|
| Descargar a disco | Sí | Sí | No | Sí |
| Subir desde disco | Sí | Sí | Sí | No |
| Eventos de progreso | Sí | Sí (progress listener) |
Sí (events) |
Sí (downloadProgress) |
| Datos de formulario multipart | Sí | Sí (por defecto) | Sí | n/a |
| PUT binario bruto (URLs presignadas) | Sí | Sí (establecer Content-Type) |
Sí (uploadType: 'binary') |
n/a |
| Multiples archivos en una solicitud | No | No | Sí (files) |
n/a |
| Cancelar | abort() |
No | removeUpload |
stop |
| Pausa / reanuda | No | No | No | pause, resume |
| Intentos | No | No | maxRetries |
No |
| Continúa en segundo plano | No | Mientras la aplicación está activa | Sí | Sí |
| Wi-Fi solo | No | No | No | network: 'wifi-only' |
| Detalles de errores HTTP | http_status, body |
httpStatus, body |
Estado code en eventos | Cadena de error en eventos |
| Implementación web | No | Sí | Sí (con base en fetch) | No |
La mayoría de las aplicaciones terminan con @capacitor/file-transfer para transferencias pequeñas visibles por el usuario y los plugins Capgo para cola de subida de medios y descarga de contenido offline.
Opción 1: @capacitor/file-transfer
bun add @capacitor/file-transfer @capacitor/filesystem
bunx cap sync
El plugin necesita una ruta nativa completa. Obténlo de @capacitor/filesystem.
Descargar
import { FileTransfer } from '@capacitor/file-transfer';
import { Filesystem, Directory } from '@capacitor/filesystem';
export async function downloadReport(url: string) {
const { uri } = await Filesystem.getUri({
directory: Directory.Data,
path: 'reports/latest.pdf',
});
const progress = await FileTransfer.addListener('progress', (p) => {
if (p.type === 'download' && p.lengthComputable) {
console.log(`Downloaded ${Math.round((p.bytes / p.contentLength) * 100)}%`);
}
});
try {
const result = await FileTransfer.downloadFile({
url,
path: uri,
progress: true,
headers: { Authorization: 'Bearer <token>' },
});
return result.path;
} catch (error: any) {
if (error.code === 'OS-PLUG-FLTR-0010') {
console.error('HTTP error', error.data?.httpStatus, error.data?.body);
}
throw error;
} finally {
await progress.remove();
}
}
Subir
export async function uploadAvatar(path: string) {
const result = await FileTransfer.uploadFile({
url: 'https://api.example.com/v1/avatar',
path,
fileKey: 'avatar',
mimeType: 'image/jpeg',
headers: { Authorization: 'Bearer <token>' },
progress: true,
});
console.log(result.responseCode, result.response);
}
Las subidas son multipart por defecto. Para un flujo bruto, por ejemplo, a una URL S3 presignada, establece method: 'PUT' y un explícito Content-Type cabecera como application/octet-stream.
Los códigos de error siguen el OS-PLUG-FLTR-XXXX formato. Los útiles son: 0007 archivo no encontrado, 0008 conexión fallida, 0010 error de estado HTTP con httpStatus y body en error.data.
Opción 2: subidas de fondo con @capgo/capacitor-uploader
bun add @capgo/capacitor-uploader
bunx cap sync
import { Uploader } from '@capgo/capacitor-uploader';
await Uploader.addListener('events', async (event) => {
switch (event.name) {
case 'uploading':
console.log(event.id, `${event.payload.percent}%`);
break;
case 'completed':
console.log(event.id, 'done', event.payload.statusCode);
break;
case 'failed':
console.error(event.id, event.payload.error);
break;
}
// Completed and failed events are cached natively until acknowledged
if (event.eventId) {
await Uploader.acknowledgeEvent({ eventId: event.eventId });
}
});
const { id } = await Uploader.startUpload({
filePath: 'file:///path/to/video.mp4',
serverUrl: 'https://api.example.com/v1/videos',
method: 'POST',
uploadType: 'multipart',
fileField: 'video',
parameters: { albumId: '7' },
headers: { Authorization: 'Bearer <token>' },
maxRetries: 3,
notificationTitle: 'Uploading video', // Android only
});
Para URLs presignadas, utilice method: 'PUT', que por defecto es un cuerpo binario:
await Uploader.startUpload({
filePath,
serverUrl: presignedUrl,
method: 'PUT',
headers: { 'Content-Type': 'video/mp4' },
mimeType: 'video/mp4',
});
Varios archivos en una solicitud multipart:
await Uploader.startUpload({
serverUrl: 'https://api.example.com/v1/photos',
method: 'POST',
uploadType: 'multipart',
files: [
{ filePath: photo1, fieldName: 'images[]', mimeType: 'image/jpeg' },
{ filePath: photo2, fieldName: 'images[]', mimeType: 'image/jpeg' },
],
headers: { Authorization: 'Bearer <token>' },
});
Cancelar con Uploader.removeUpload({ id }).
¿Por qué reconocer eventos? Los eventos completados y fallidos se almacenan en una caché nativa persistente, por lo que se pueden reenviar si la aplicación estaba cerrada o en segundo plano antes de que la manejaran. Reconocer elimina el evento para que no se retransmita la próxima vez que el plugin inicie.
iOS setup. El subidor utiliza un fondo URLSession. Many apps need no extra setup. If uploads must continue after the app is suspended, add fetch Para UIBackgroundModesNo agregue nada processing a menos que otra característica utilice BGTaskScheduler, porque App Store Connect rechaza los builds que declaran sin ella BGTaskSchedulerPermittedIdentifiers.
Opción 3: descargas de fondo con @capgo/capacitor-descargador
bun add @capgo/capacitor-downloader
bunx cap sync
import { CapacitorDownloader } from '@capgo/capacitor-downloader';
await CapacitorDownloader.addListener('downloadProgress', ({ id, progress }) => {
console.log(id, `${progress}%`);
});
await CapacitorDownloader.addListener('downloadCompleted', ({ id }) => {
console.log(id, 'completed');
});
await CapacitorDownloader.addListener('downloadFailed', ({ id, error }) => {
console.error(id, error);
});
await CapacitorDownloader.download({
id: 'course-42',
url: 'https://cdn.example.com/courses/42.zip',
destination: 'courses/42.zip',
headers: { Authorization: 'Bearer <token>' },
network: 'wifi-only',
priority: 'normal',
notification: 'progress', // Android: remove the system notification when done
});
// Later
await CapacitorDownloader.pause({ id: 'course-42' });
await CapacitorDownloader.resume({ id: 'course-42' });
const status = await CapacitorDownloader.checkStatus({ id: 'course-42' });
console.log(status.state, status.progress);
Un pariente destination se resuelve a la carpeta de documentos del app en iOS y a la carpeta de archivos externos específicos del app en Android. También puedes pasar una ruta absoluta o un file:// Usa getFileInfo({ path }) después de descargar, leer el tamaño y el tipo MIME stop({ id }) para cancelar y eliminar datos parciales.
Migrar desde cordova-plugin-file-transfer
Descargar
// Before
const ft = new FileTransfer();
ft.onprogress = (e) => e.lengthComputable && setProgress(e.loaded / e.total);
ft.download(
encodeURI(url),
cordova.file.dataDirectory + 'report.pdf',
(entry) => console.log(entry.toURL()),
(err) => console.error(err.code, err.http_status),
false,
{ headers: { Authorization: 'Bearer <token>' } },
);
// After
const { uri } = await Filesystem.getUri({ directory: Directory.Data, path: 'report.pdf' });
await FileTransfer.downloadFile({
url,
path: uri,
progress: true,
headers: { Authorization: 'Bearer <token>' },
});
Subir
// Before
const options = new FileUploadOptions();
options.fileKey = 'file';
options.fileName = 'photo.jpg';
options.mimeType = 'image/jpeg';
options.params = { albumId: '7' };
options.headers = { Authorization: 'Bearer <token>' };
new FileTransfer().upload(fileUrl, encodeURI(serverUrl), onSuccess, onError, options);
// After, foreground
await FileTransfer.uploadFile({
url: serverUrl,
path: fileUrl,
fileKey: 'file',
mimeType: 'image/jpeg',
params: { albumId: '7' },
headers: { Authorization: 'Bearer <token>' },
});
// After, background
await Uploader.startUpload({
filePath: fileUrl,
serverUrl,
uploadType: 'multipart',
fileField: 'file',
parameters: { albumId: '7' },
headers: { Authorization: 'Bearer <token>' },
});
Nota que params en @capacitor/file-transfer son parámetros de consulta de URL. Si su servidor espera campos de formulario, utilice el subidor de Capgo parameters, que se envían como campos de formulario multipart.
Tabla de correspondencia
| cordova-plugin-file-transfer | @capacitor/file-transfer | Capgo plugins |
|---|---|---|
download(source, target, ...) |
downloadFile({ url, path }) |
CapacitorDownloader.download({ id, url, destination }) |
upload(file, server, ...) |
uploadFile({ url, path }) |
Uploader.startUpload({ filePath, serverUrl }) |
onprogress |
addListener('progress') |
addListener('events') / addListener('downloadProgress') |
abort() |
No disponible | removeUpload({ id }) / stop({ id }) |
options.fileKey |
fileKey |
fileField o files[].fieldName |
options.params |
params No hay texto para traducir. |
parameters (parámetro de consulta) |
options.httpMethod |
method |
method (POST o PUT) |
options.chunkedMode |
chunkedMode |
(campos de formulario) |
cordova.file.dataDirectory |
Filesystem.getUri({ directory: Directory.Data }) |
Manejado nativamente file:// URL |
FileTransferError.http_status |
error.data.httpStatus |
event.payload.statusCode |
Rutas: la parte que rompe las migraciones
Cordova code pasa cdvfile:// o cordova.file.* ¿Otra alternativa a Capacitor?
- ¿Otra alternativa a __CAPGO_KEEP_0__?
Filesystem.getUri()o desde el plugin que creó el archivo (cámara, selector de archivo, grabador). - Para mostrar una imagen descargada en la WebView, convierta la ruta nativa con __CAPGO_KEEP_0__.
Capacitor.convertFileSrc(path). - Capgo tiene un plugin de archivo y un file picker if
@capacitor/filesystem¿Otra alternativa a __CAPGO_KEEP_0__?
Troubleshooting
Subir archivos funciona en Android pero falla en iOS con un error de archivo no encontrado. Usted pasó una capacitor:// URL de WebView en lugar de una ruta nativa. file:// Utilice la ruta desde Filesystem.getUri().
El servidor rechaza la subida con 415. Multipart vs cuerpo bruto desalineado. Para URLs presignadas utilice PUT con un enfoque explícito Content-Type.
Las subidas de fondo se detienen en iOS. El usuario cerró la aplicación, lo que cancela las sesiones de fondo, o fetch El modo de fondo está ausente cuando lo necesita.
Android muestra una notificación de descarga congelada. Establecer notification: 'progress' o 'hidden' en el descargador.
Crash de memoria en descargas grandes. Usted todavía está utilizando fetch o leyendo el archivo como base64 a través del puente. Cambie a una descarga nativa a disco.
Envíe la migración
Intercambiar plugins nativos requiere una nueva compilación de tienda, que Capgo Compilación puede ejecutarse en la nube para iOS y Android. Después de eso, el JavaScript que impulsa las subidas y descargas se puede corregir e mejorar con Capgo actualizaciones en vivo. Para el resto del Cordova a Capacitor mover, consulte nuestro Guía de migracióny para otros SDK nativos pagados o legados, el Alternativas de plugins de Ionic enterprise.