简体   繁体   English

XMLHttpRequest POST multipart / form-data

[英]XMLHttpRequest POST multipart/form-data

I want to use XMLHttpRequest in JavaScript to POST a form that includes a file type input element so that I can avoid page refresh and get useful XML back. 我想在JavaScript中使用XMLHttpRequest来POST一个包含文件类型输入元素的表单,这样我就可以避免页面刷新并获得有用的XML。

I can submit the form without page refresh, using JavaScript to set the target attribute on the form to an iframe for MSIE or an object for Mozilla, but this has two problems. 我可以在没有页面刷新的情况下提交表单,使用JavaScript将表单上的目标属性设置为MSIE的iframe或Mozilla的对象,但这有两个问题。 The minor problem is that target is not W3C compliant (which is why I set it in JavaScript, not in XHTML). 小问题是目标不符合W3C(这就是为什么我在JavaScript中设置它,而不是在XHTML中设置它)。 The major problem is that the onload event doesn't fire, at least not on Mozilla on OS X Leopard. 主要问题是onload事件不会触发,至少不会触发OS X Leopard上的Mozilla。 Besides, XMLHttpRequest would make for prettier response code because the returned data could be XML, not confined to XHTML as is the case with iframe. 此外,XMLHttpRequest会产生更漂亮的响应代码,因为返回的数据可能是XML,而不是像iframe那样仅限于XHTML。

Submitting the form results in HTTP that looks like: 提交表单会产生如下HTTP的HTTP:

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>

How do I get the XMLHttpRequest object's send method to duplicate the above HTTP stream? 如何获取XMLHttpRequest对象的send方法来复制上述HTTP流?

You can construct the 'multipart/form-data' request yourself (read more about it at http://www.faqs.org/rfcs/rfc2388.html ) and then use the send method (ie. xhr.send(your-multipart-form-data)). 你可以自己构建'multipart / form-data'请求(在http://www.faqs.org/rfcs/rfc2388.html上阅读更多相关信息),然后使用send方法(即xhr.send(你的 - )多部分形式的数据))。 Similarly, but easier, in Firefox 4+ (also in Chrome 5+ and Safari 5+) you can use the FormData interface that helps to construct such requests. 同样,但更容易,在Firefox 4+(也在Chrome 5+和Safari 5+中),您可以使用FormData接口来帮助构建此类请求。 The send method is good for text content but if you want to send binary data such as images, you can do it with the help of the sendAsBinary method that has been around starting with Firefox 3.0. send方法适用于文本内容,但是如果要发送二进制数据(如图像),可以使用从Firefox 3.0开始的sendAsBinary方法来完成。 For details on how to send files via XMLHttpRequest , please refer to http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html . 有关如何通过XMLHttpRequest发送文件的详细信息,请参阅http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html

There isn't any way to access a file input field inside javascript so there isn't a javascript only solution for ajax file uploads. 没有任何方法可以访问javascript中的文件输入字段,因此没有针对ajax文件上传的javascript解决方案。

There are workaround like using an iframe . 使用iframe的解决方法。

The other option would be to use something like SWFUpload or Google Gears 另一种选择是使用SWFUploadGoogle Gears之类的东西

I don't see why iframe (an invisible one) implies XHTML and not ANY content. 我不明白为什么iframe(一个看不见的)暗示XHTML而不是任何内容。 If you use an iframe you can set the onreadystatechange event and wait for 'complete'. 如果您使用iframe,则可以设置onreadystatechange事件并等待“完成”。 Next you could use frame.window.document.innerHTML (please someone correct me) to get the string result. 接下来你可以使用frame.window.document.innerHTML(请有人纠正我)来获取字符串结果。

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

You will need to POST to an IFrame to get this to work, simply add a target attribute to your form, where you specify the IFrame ID. 您需要POST到IFrame才能使其生效,只需在表单中添加目标属性,您可以在其中指定IFrame ID。 Something like this: 像这样的东西:


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

i am confuse about the onload event that you specified, it is on the page or on iframe?, the first answer is correct theres no way to do this using purely xmlhttprequest, if what you want to acheive is triggering some method once the response exist on iframe, simply check if it has content already or not using DOM scripting, then fire the method. 我对你指定的onload事件感到困惑,它是在页面上还是在iframe上?,第一个答案是正确的,没有办法使用纯xmlhttprequest这样做,如果你想要实现的是一旦响应存在就触发一些方法在iframe上,只需检查它是否已经使用DOM脚本编写内容,然后触发该方法。

to attach onload event to the iframe 将onload事件附加到iframe

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

Here is an up to date way using FormData ( full doc @MDN ) 这是使用FormData的最新方法( 完整文档@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();
});

(from this basic form) (从这个基本形式)

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

Thanks again to Alex Polo for his answer 再次感谢Alex Polo的回答

Content-Disposition: form-data, name 内容处理:表单数据,名称

You should use semicolon, like this: Content-Disposition: form-data; 你应该使用分号,如下所示:Content-Disposition:form-data; name 名称

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM