JavaScript: subir archivo

190

Digamos que tengo este elemento en la página:

<input id="image-file" type="file" />

Esto creará un botón que permite a los usuarios de la página web seleccionar un archivo a través de un cuadro de diálogo "Abrir archivo ..." del sistema operativo en el navegador.

Digamos que el usuario hace clic en dicho botón, selecciona un archivo en el cuadro de diálogo y luego hace clic en el botón "Aceptar" para cerrar el cuadro de diálogo.

El nombre del archivo seleccionado ahora se almacena en:

document.getElementById("image-file").value

Ahora, supongamos que el servidor maneja las POST de varias partes en la URL "/ upload / image".

¿Cómo envío el archivo a "/ upload / image"?

Además, ¿cómo escucho las notificaciones de que el archivo ha terminado de cargarse?

YummyBánhMì
fuente
2
JavaScript no maneja las cargas, porque está en el lado del servidor. El script del lado del servidor recibirá el archivo y luego lo moverá. Para php de la carpeta temporal a la carpeta deseada.
Bakudan
15
Voté para volver a abrir porque la pregunta es sobre POJS (javascript antiguo simple) no jQuery.
e2-e4

Respuestas:

95

A menos que esté intentando cargar el archivo usando ajax, simplemente envíe el formulario a /upload/image.

<form enctype="multipart/form-data" action="/upload/image" method="post">
    <input id="image-file" type="file" />
</form>

Si desea cargar la imagen en segundo plano (por ejemplo, sin enviar el formulario completo), puede usar ajax:

Matt Ball
fuente
o tamaño de iframe 0x0 con script de cargador de imágenes dentro de su src = "" y publique el formulario en él usando target = "iframeId" leyendo el resultado en el evento iframe src .load que puede vincularse usando jQuery, por ejemplo.
Dmitry
11
En realidad, es posible votar a través de Javascript y Ajax hoy en día, ver: stackoverflow.com/a/10811427/694469 (no voté a favor).
KajMagnus
35
@KajMagnus, probablemente quisiste decir 'subir' pero accidentalmente dijiste 'voto positivo'
Samuel Allan
85

JS puro

Puede usar fetch opcionalmente con await-try-catch

let photo = document.getElementById("image-file").files[0];
let formData = new FormData();

formData.append("photo", photo);
fetch('/upload/image', {method: "POST", body: formData});

Enfoque de la vieja escuela - xhr

let photo = document.getElementById("image-file").files[0];  // file from input
let req = new XMLHttpRequest();
let formData = new FormData();

formData.append("photo", photo);                                
req.open("POST", '/upload/image');
req.send(formData);

RESUMEN

  • En el lado del servidor, puede leer el nombre del archivo original (y otra información) que se incluye automáticamente para solicitar por navegador en el filenameparámetro formData.
  • NO es necesario establecer el encabezado de la solicitud Content-Typeen multipart/form-data: el navegador lo configurará automáticamente.
  • En lugar de /upload/imageusted puede usar la dirección completa como http://.../upload/image.
  • Si desea enviar muchos archivos en una sola solicitud, utilice el multipleatributo: <input multiple type=... />y adjunte todos los archivos elegidos a formData de manera similar (por ejemplo photo2=...files[2];... formData.append("photo2", photo2);)
  • Puede incluir datos adicionales (json) para solicitar, por ejemplo, let user = {name:'john', age:34}de esta manera:formData.append("user", JSON.stringify(user));
  • Estas soluciones deberían funcionar en todos los principales navegadores.
Kamil Kiełczewski
fuente
Trabaja perfectamente para mi.
Trieu Nguyen
formData === formulario enviarenctype="multipart/form-data"
xgqfrms
Recibo un errornet::ERR_ABORTED 405 (Method Not Allowed)
Hidayt Rahman
@HidaytRahman este error generalmente aparece cuando el servidor no implementa el método POST para su URL
Kamil Kiełczewski
1
Extraño: según su título, pensaba que ya no necesitábamos servidor: D
Hidayt Rahman