20

我想在 JavaScript 中使用 XMLHttpRequest 来发布一个包含文件类型输入元素的表单,这样我就可以避免页面刷新并返回有用的 XML。

我可以在不刷新页面的情况下提交表单,使用 JavaScript 将表单上的目标属性设置为 MSIE 的 iframe 或 Mozilla 的对象,但这有两个问题。小问题是目标不符合 W3C(这就是我在 JavaScript 中设置它的原因,而不是在 XHTML 中)。主要问题是 onload 事件不会触发,至少在 OS X Leopard 上的 Mozilla 上不会。此外,XMLHttpRequest 将使响应代码更漂亮,因为返回的数据可以是 XML,而不是像 iframe 那样仅限于 XHTML。

提交表单会产生如下所示的 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>

如何让 XMLHttpRequest 对象的 send 方法复制上述 HTTP 流?

4

7 回答 7

26

您可以自己构造“multipart/form-data”请求(在http://www.faqs.org/rfcs/rfc2388.html上阅读更多信息),然后使用该send方法(即 xhr.send(your-multipart -表格数据))。同样,但更简单的是,在 Firefox 4+(也在 Chrome 5+ 和 Safari 5+)中,您可以使用FormData接口来帮助构建此类请求。该send方法适用于文本内容,但如果您想发送图像等二进制数据,您可以借助sendAsBinary从 Firefox 3.0 开始的方法来完成。关于如何通过 发送文件的详细信息XMLHttpRequest,请参考http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html

于 2010-11-21T23:02:18.970 回答
5

没有任何方法可以访问 javascript 中的文件输入字段,因此没有仅用于 ajax 文件上传的 javascript 解决方案。

有一些解决方法,比如使用 iframe

另一种选择是使用SWFUploadGoogle Gears之类的东西

于 2008-09-30T22:42:40.747 回答
0

我不明白为什么 iframe(一个不可见的)意味着 XHTML 而不是任何内容。如果您使用 iframe,您可以设置 onreadystatechange 事件并等待“完成”。接下来,您可以使用 frame.window.document.innerHTML (请有人纠正我)来获取字符串结果。

var lFrame = document.getElementById('myframe');
lFrame.onreadystatechange = function()
{
   if (lFrame.readyState == 'complete')
   {
      // your frame is done, get the content...
   }
};
于 2008-09-30T22:42:31.577 回答
0

您需要 POST 到 IFrame 才能使其正常工作,只需将 target 属性添加到您的表单中,您可以在其中指定 IFrame ID。像这样的东西:


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

于 2008-09-30T22:45:52.800 回答
0

我对您指定的 onload 事件感到困惑,它是在页面上还是在 iframe 上?,第一个答案是正确的,如果您想要实现的是在响应存在时触发某个方法,则无法使用纯粹的 xmlhttprequest 来执行此操作在 iframe 上,只需使用 DOM 脚本检查它是否已经有内容,然后触发该方法。

将 onload 事件附加到 iframe

if(window.attachEvent){
 document.getElementById(iframe).attachEvent('onload', some_method);
}else{
 document.getElementById(iframe).addEventListener('load', some_method, false);
} 
于 2008-10-04T18:15:57.040 回答
0

内容处置:表单数据,名称

您应该使用分号,如下所示: Content-Disposition: form-data; 姓名

于 2011-06-29T15:27:23.887 回答
0

这是使用 FormData 的最新方式(完整文档 @MDN

脚本:

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

(从这个基本形式)

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

再次感谢 Alex Polo 的回答

于 2017-12-31T13:58:56.107 回答