XMLHttpRequest POST multipart / form-data
-
03-07-2019 - |
Domanda
Voglio usare XMLHttpRequest in JavaScript per POST un modulo che include un elemento di input del tipo di file in modo da poter evitare l'aggiornamento della pagina e recuperare utile XML.
Posso inviare il modulo senza aggiornamento della pagina, usando JavaScript per impostare l'attributo target sul modulo su un iframe per MSIE o un oggetto per Mozilla, ma questo ha due problemi. Il problema minore è che target non è conforme al W3C (motivo per cui l'ho impostato in JavaScript, non in XHTML). Il problema principale è che l'evento onload non si attiva, almeno non su Mozilla su OS X Leopard. Inoltre, XMLHttpRequest renderebbe il codice di risposta più bello perché i dati restituiti potrebbero essere XML, non limitati a XHTML come nel caso di iframe.
L'invio del modulo comporta un HTTP simile a:
Content-Type: multipart/form-data;boundary=<boundary string>
Content-Length: <length>
--<boundary string>
Content-Disposition: form-data, name="<input element name>"
<input element value>
--<boundary string>
Content-Disposition: form-data, name=<input element name>"; filename="<input element value>"
Content-Type: application/octet-stream
<element body>
Come posso ottenere il metodo di invio dell'oggetto XMLHttpRequest per duplicare il flusso HTTP sopra?
Soluzione
Puoi costruire tu stesso la richiesta "multipart / form-data" (leggi di più su http : //www.faqs.org/rfcs/rfc2388.html ) e quindi usa il metodo send
(es. xhr.send (your-multipart-form-data)). Allo stesso modo, ma più facile, in Firefox 4+ (anche in Chrome 5+ e Safari 5+) è possibile utilizzare FormData che aiuta a costruire tali richieste. Il metodo send
è utile per i contenuti di testo ma se si desidera inviare dati binari come immagini, è possibile farlo con l'aiuto del metodo sendAsBinary
che è stato avviato all'inizio con Firefox 3.0. Per dettagli su come inviare file tramite XMLHttpRequest
, fare riferimento a http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html .
Altri suggerimenti
Non esiste alcun modo per accedere a un campo di input di file all'interno di javascript, quindi non esiste una soluzione solo javascript per i caricamenti di file ajax.
Esistono soluzioni alternative come utilizzando un iframe .
L'altra opzione sarebbe quella di usare qualcosa come SWFUpload o Google Gears
Non vedo perché iframe (invisibile) implichi XHTML e non QUALSIASI contenuto. Se usi un iframe puoi impostare l'evento onreadystatechange e attendere 'complete'. Successivamente potresti usare frame.window.document.innerHTML (per favore qualcuno mi corregga) per ottenere il risultato della stringa.
var lFrame = document.getElementById('myframe');
lFrame.onreadystatechange = function()
{
if (lFrame.readyState == 'complete')
{
// your frame is done, get the content...
}
};
Dovrai POSTARE a un IFrame per farlo funzionare, aggiungi semplicemente un attributo target al tuo modulo, dove specifichi l'ID IFrame. Qualcosa del genere:
<form method="post" target="myiframe" action="handler.php">
...
</form>
<iframe id="myiframe" style="display:none" />
Sono confuso sull'evento onload che hai specificato, è sulla pagina o su iframe ?, la prima risposta è corretta, non c'è modo di farlo usando puramente xmlhttprequest, se ciò che si desidera ottenere sta attivando un metodo una volta che la risposta esiste su iframe, è sufficiente verificare se ha già contenuto o non utilizzare lo script DOM, quindi attivare il metodo.
per collegare l'evento onload all'iframe
if(window.attachEvent){
document.getElementById(iframe).attachEvent('onload', some_method);
}else{
document.getElementById(iframe).addEventListener('load', some_method, false);
}
Disposizione dei contenuti: form-data, name
Dovresti usare il punto e virgola, in questo modo: Content-Disposition: form-data; nome
Ecco un modo aggiornato usando FormData ( full doc @MDN )
Script:
var form = document.querySelector('#myForm');
form.addEventListener("submit", function(e) {
var xhr = new XMLHttpRequest();
xhr.open("POST", this.action);
xhr.addEventListener("load", function(e) {
// Your callback
});
xhr.send(new FormData(this));
e.preventDefault();
});
(da questo modulo di base)
<form id="myForm" action="..." method="POST" enctype="multipart/form-data">
<input type="file" name="file0">
<input type="text" name="some-text">
...
</form>
Grazie ancora ad Alex Polo per la sua risposta