¡Es posible! Lee abajo.
En primer lugar, permítanme usar este diagrama para explicar cómo se pueden lograrla carga de archivos asíncronos:¿Es posible realizar una carga de archivos asíncrona entre dominios?
Lo sentimos. Cerré uno de mis dominios y la imagen ya no está. Aunque fue una imagen realmente bonita. Esto fue antes de descubrir que Stack Overflow permite subir imágenes a través de Imgur.
Como se puede ver, el truco es dejar que la carga HTTP de respuesta en un elemento IFRAME oculto en lugar de la propia página. (Esto se hace configurando la propiedad target
del elemento FORM al enviar el FORMULARIO con JavaScript.)
Esto funciona. Sin embargo, el problema que estoy enfrentando es que el script del lado del servidor está en un dominio diferente . El FORM-submit es una solicitud HTTP entre dominios. Ahora, el script del lado del servidor tiene CORS habilitado, lo que le da a mi página web los derechos para leer los datos de respuesta de las solicitudes HTTP hechas desde mi página a esa secuencia de comandos, pero eso solo funciona si recibo la respuesta HTTP a través de Ajax. ergo, JavaScript.
Sin embargo, en este caso, la respuesta se dirige hacia el elemento IFRAME. Y una vez que la respuesta XML llega al IFRAME, su URL será la secuencia de comandos eliminada, p. http://remote-domain.com/script.pl
.
Lamentablemente, CORS no cubre este caso (al menos creo que) - No puedo leer el contenido de IFRAME porque su URL no coincide con la URL de la página (dominio diferente). Me sale este error:
Unsafe JavaScript attempt to access frame with URL hxxp://remote-domain.com/script.pl from frame with URL hxxp://my-domain.com/outer.html. Domains, protocols and ports must match.
Y puesto que el contenido del IFRAME es un documento XML, no hay ningún código JavaScript dentro del IFRAME que podría hacer uso de postMessage
o algo así.
Así que mi pregunta es: ¿Cómo puedo obtener los contenidos XML del IFRAME?
Como dije anteriormente, puedo recuperar las respuestas HTTP entre dominios directamente (CORS habilitado), pero parece que no puedo leer las respuestas HTTP entre dominios una vez que se cargan en un IFRAME.
Y como si esta pregunta no es suficiente sin solución, que me excluir estas soluciones:
easyXDM y técnicas similares que requieren un punto final en el dominio remoto,
que altera la respuesta XML (para incluir un elemento SCRIPT),
proxy del lado del servidor - Entiendo que podría tener un script del lado del servidor en mi dominio que podría servir como un proxy.
Entonces, aparte de esas dos soluciones, ¿se puede hacer esto?
Se puede hacer !!
Resulta que es posible forjar una solicitud XHR (petición Ajax) que imita un envío de formulario multipart/form-data
(que se utiliza en la imagen de arriba para cargar el archivo en el servidor).
El truco es usar el constructor FormData
- lea this Mozilla Hacks article para obtener más información.
Esta es la forma de hacerlo:
// STEP 1
// retrieve a reference to the file
// <input type="file"> elements have a "files" property
var file = input.files[0];
// STEP 2
// create a FormData instance, and append the file to it
var fd = new FormData();
fd.append('file', file);
// STEP 3
// send the FormData instance with the XHR object
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://remote-domain.com/script.pl', true);
xhr.onreadystatechange = responseHandler;
xhr.send(fd);
El método anterior se ejecuta un archivo-uplaod asíncrona, lo que equivale a la carga de archivos periódica descrita en la imagen anterior y ha logrado mediante la presentación de esta forma:
<form action="http://remote-domain.com/script.pl"
enctype="multipart/form-data" method="post">
<input type="file" name="file">
</form>
Si no puede editar la respuesta de los servidores remotos, entonces no. Puede usar un truco de intercambio o postmensaje si puede editar el origen del sitio de carga. – William
Si no te importan tanto los navegadores antiguos, puedes usar un método de carga más común en el que subas el archivo a JS y lo publiques a través de AJAX. Si esto parece una buena idea, házmelo saber y lo publicaré como respuesta. –
@Thomas No me interesan los navegadores más antiguos; de hecho, estoy bien incluso si funciona en un solo navegador ':)'. ¿Podrías elaborar un poco más? Me temo que el script del servidor espera un '