2008-09-30 4 views
17

Ich möchte XMLHttpRequest in JavaScript verwenden, um ein Formular zu senden, das ein Dateityp-Eingabeelement enthält, damit ich Seitenaktualisierung vermeiden und nützliches XML zurück erhalten kann.XMLHttpRequest POST multipart/form-data

Ich kann das Formular ohne Seitenaktualisierung übergeben, mithilfe von JavaScript, um das Zielattribut im Formular auf einen Iframe für MSIE oder ein Objekt für Mozilla festzulegen, aber das hat zwei Probleme. Das kleinere Problem ist, dass das Ziel nicht W3C-konform ist (weshalb ich es in JavaScript und nicht in XHTML einstelle). Das Hauptproblem ist, dass das Onload-Ereignis nicht ausgelöst wird, zumindest nicht auf Mozilla unter OS X Leopard. Außerdem würde XMLHttpRequest für einen schöneren Antwortcode sorgen, da die zurückgegebenen Daten XML sein könnten und nicht auf XHTML beschränkt wären, wie es bei iframe der Fall ist.

Absenden des Formulars Ergebnisse in HTTP, die wie folgt aussieht:

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> 

Wie erhalte ich die Sendemethode das XMLHttpRequest-Objekt der obigen HTTP-Stream zu duplizieren?

+0

Sie haben eine Antwort nach 9 Jahren akzeptiert! Du bist der Zweite damit auf dem Stapel. – peterh

Antwort

23

Sie können Anfrage die 'multipart/form-data' konstruieren selbst und verwenden Sie dann die send Methode (dh. Xhr (mehr darüber in http://www.faqs.org/rfcs/rfc2388.html lesen). sende (deine-multipart-form-data)). Ähnlich, aber einfacher, können Sie in Firefox 4+ (auch in Chrome 5+ und Safari 5+) die Schnittstelle FormData verwenden, die dabei hilft, solche Anfragen zu erstellen. Die Methode send eignet sich gut für Textinhalte, aber wenn Sie Binärdaten wie Bilder senden möchten, können Sie dies mit Hilfe der Methode sendAsBinary tun, die seit Firefox 3.0 verfügbar ist. Einzelheiten zum Senden von Dateien über XMLHttpRequest finden Sie unter http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html.

+0

Heilige ***. Vielen Dank! Ich habe versucht, herauszufinden, wie man das manuell für eine Stunde macht, wobei mein Server das, was ich gesendet habe, nicht parsen kann –

0

Ich sehe nicht, warum iframe (eine unsichtbare) XHTML und nicht irgendeinen Inhalt impliziert. Wenn Sie einen iframe verwenden, können Sie das Ereignis onreadystatechange setzen und auf 'complete' warten. Als nächstes könnten Sie frame.window.document.innerHTML verwenden (bitte korrigieren Sie mich), um das String-Ergebnis zu erhalten.

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

Es gibt keine Möglichkeit, eine Datei Eingabefeld innerhalb Javascript zuzugreifen, so kein Javascript es für Ajax-Datei-Uploads einzige Lösung ist.

Es gibt Workaround wie using an iframe.

Die andere Möglichkeit wäre, etwas zu verwenden, wie SWFUpload oder Google Gears

0

Sie müssen zu einem IFrame, um es zu diesem, an der Arbeit einfach ein Zielattribut zu Ihrem Formular hinzufügen, in dem Sie die IFrame-ID angeben. Etwas wie folgt aus:

 

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

ich bin verwirren über das Onload-Ereignis, die Sie angegeben, es auf der Seite oder auf iframe ?, die erste Antwort ist richtig Theres keine Möglichkeit, diese mit rein xmlhttprequest zu tun, wenn das, was Sie möchten erreichen, dass eine Methode ausgelöst wird, sobald die Antwort auf iframe existiert. Überprüfen Sie einfach, ob der Inhalt bereits vorhanden ist oder nicht, indem Sie DOM-Scripting verwenden, und feuern Sie die Methode ab.

onload Ereignis an den iframe befestigen

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

Content-Disposition: form-data, Name

Sie Semikolon verwenden sollten, wie folgt aus: Content-Disposition: form-data; Name

0

Hier ist ein nach oben Art und Weise bisher mit Formdata (full doc @MDN)

Drehbuch:

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(); 
}); 

(von dieser Grundform)

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

Nochmals vielen Dank an Alex Polo für seine Antwort