2008-09-30 5 views
17

Je souhaite utiliser XMLHttpRequest en JavaScript pour POST un formulaire qui inclut un élément d'entrée de type fichier afin que je puisse éviter l'actualisation de la page et récupérer le code XML utile.XMLHttpRequest POST multipart/form-data

Je peux soumettre le formulaire sans actualisation de page, en utilisant JavaScript pour définir l'attribut cible sur le formulaire à un iframe pour MSIE ou un objet pour Mozilla, mais cela a deux problèmes. Le problème mineur est que la cible n'est pas conforme au W3C (c'est pourquoi je l'ai mis en JavaScript, pas en XHTML). Le problème majeur est que l'événement onload ne se déclenche pas, du moins pas sur Mozilla sous OS X Leopard. En outre, XMLHttpRequest rendrait le code de réponse plus joli parce que les données renvoyées pourraient être XML, pas confinées à XHTML comme c'est le cas avec iframe.

Soumettre le formulaire HTTP dans les résultats qui ressemble à:

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> 

Comment puis-je obtenir la méthode d'envoi de l'objet XMLHttpRequest pour dupliquer le flux HTTP ci-dessus?

+0

Vous avez accepté une réponse après 9 ans! Vous êtes le deuxième sur le stackexchange. – peterh

Répondre

23

Vous pouvez construire la demande 'des données de formulaire-multipart /' vous (en savoir plus à ce sujet à http://www.faqs.org/rfcs/rfc2388.html), puis utiliser la méthode send (ie. De XHR. send (your-multipart-form-data)). De même, mais plus facilement, dans Firefox 4+ (également dans Chrome 5+ et Safari 5+), vous pouvez utiliser l'interface FormData qui permet de construire de telles requêtes. La méthode send est bonne pour le contenu textuel, mais si vous voulez envoyer des données binaires telles que des images, vous pouvez le faire avec l'aide de la méthode sendAsBinary qui a débuté avec Firefox 3.0. Pour plus de détails sur l'envoi de fichiers via XMLHttpRequest, veuillez vous reporter au http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html.

+0

Saint ***. Je vous remercie! J'ai essayé de comprendre comment faire cela manuellement pendant une heure avec mon serveur incapable d'analyser ce que j'ai envoyé –

0

Je ne vois pas pourquoi iframe (un invisible) implique XHTML et pas n'importe quel contenu. Si vous utilisez un iframe, vous pouvez définir l'événement onreadystatechange et attendre 'complete'. Ensuite, vous pouvez utiliser frame.window.document.innerHTML (s'il vous plaît quelqu'un me corriger) pour obtenir le résultat de la chaîne.

var lFrame = document.getElementById('myframe'); 
lFrame.onreadystatechange = function() 
{ 
    if (lFrame.readyState == 'complete') 
    { 
     // your frame is done, get the content... 
    } 
}; 
5

Il n'y a pas moyen d'accéder à un champ d'entrée de fichier à l'intérieur javascript donc il n'y a pas javascript seule solution pour le téléchargement de fichiers ajax. Il existe des solutions de contournement telles que using an iframe.

L'autre option serait d'utiliser quelque chose comme SWFUpload ou Google Gears

0

Vous devrez POST à ​​un IFrame pour que cela fonctionne, il suffit d'ajouter un attribut cible à votre formulaire, vous permet de spécifier l'ID iFrame. Quelque chose comme ceci:

 

<form method="post" target="myiframe" action="handler.php"> 
... 
</form> 
<iframe id="myiframe" style="display:none" /> 
 
0

je suis confondez sur l'événement onload que vous avez spécifié, il est sur la page ou sur iframe ?, la première réponse est correcte Theres aucun moyen de le faire en utilisant uniquement XMLHttpRequest, si ce vous voulez réaliser une méthode lorsque la réponse existe sur iframe, vérifiez simplement si le contenu est déjà utilisé ou non, puis lancez la méthode.

pour fixer l'événement onload à l'iframe

if(window.attachEvent){ 
document.getElementById(iframe).attachEvent('onload', some_method); 
}else{ 
document.getElementById(iframe).addEventListener('load', some_method, false); 
} 
0

Content-Disposition: form-data, nom

Vous devez utiliser virgule, comme ceci: Content-Disposition: form-data; nommer

0

Voici un à façon jour à l'aide 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(); 
}); 

(de cette forme de base)

<form id="myForm" action="..." method="POST" enctype="multipart/form-data"> 
    <input type="file" name="file0"> 
    <input type="text" name="some-text"> 
    ... 
</form> 

Merci encore à Alex Polo pour son answer

Questions connexes