【问题标题】:How to make Asynchronous(AJAX) File Upload using iframe?如何使用 iframe 进行异步(AJAX)文件上传?
【发布时间】:2011-02-23 23:09:22
【问题描述】:

我正在尝试进行 ajax 文件上传。我读到如果不使用 iframe 是不可能做到这一点的。
我写道:

<iframe id="uploadTrg" name="uploadTrg" height="0" width="0" frameborder="0" scrolling="yes"></iframe>
<form id="myForm" action="file-component" method="post" enctype="multipart/form-data"  target="uploadTrg">
File: <input type="file" name="file">
<input type="submit" value="Submit" id="submitBtn"/>
</form>

并使用 jquery 表单插件:

$('#myForm').ajaxForm({
    dataType:  'json',
    success:   function(data){
        alert(data.toSource());
    }
});

结果:

文件上传成功,我可以看到上传的文件,但出现一个对话框:

因为我发回了一个 json 结果以显示文件名 + 大小等..

我的问题: 如何使用 iFrame 进行“ajax 文件上传”。

注意:

  1. 如果有更合适/更简单的解决方案,我不喜欢使用特殊插件上传文件。
  2. 我使用 jsp/servlets 作为服务器端语言 .. 但我认为我使用哪种语言没有意义。

谢谢

【问题讨论】:

  • 在您的#1 中,您指的是 jQuery 插件,还是指 Flash/Silverlight?
  • 我在不使用 JavaScript 的情况下设计了一个更简化的 ajax 样式文件上传页面。我在表单标签之前放置了一个隐藏的 iFrame。请阅读以下内容。 ramui.com/articles/ajax-file-upload-using-iframe.html

标签: jquery ajax servlets file-upload


【解决方案1】:

这个例子取自 BugKiller。完整的工作示例,允许您上传徽标并立即在 html 页面中看到它,然后上传值被清除:

html:

<form id="uploadForm" method="post" enctype="multipart/form-data"  target="uploadTrg">
  <div id="fileUploadWrapper"><input type="file" name="file" id="fileUpload"></div>
  <input type="submit" value="Upload" id="submitBtn"/>
</form>
<iframe id="uploadTrg" name="uploadTrg" height="0" width="0" frameborder="0" scrolling="no" style="display:none"></iframe>
<img id="imgLogo" style="border-width:0px;" />

javascript:

$(document).ready(function () {
  var companynumber = '12345'; //get this from the database
  var logoUploadUrl = 'UploadHandler.aspx?logoupload=true&companynumber=' + companynumber ;
  $("#uploadForm").attr("action", logoUploadUrl);

  $("#uploadTrg").load(function () {
    //upload complete

    //only way to reset contents of file upload control is to recreate it
    $("#fileUploadWrapper").html('<input type="file" name="file" id="fileUpload">');

    //reload the logo url, add ticks on the end so browser reloads it
    var ticks = ((new Date().getTime() * 10000) + 621355968000000000);
    var logoUrl = 'images/clients/' + companynumber + '/client.gif?' + ticks;
    $("#imgLogo").attr('src', logoUrl);
  });
});

在后面上传处理程序代码(C#):

namespace MyWebApp {
    public partial class UploadHandler : System.Web.UI.Page {

        protected void Page_Load(object sender, EventArgs e) {
          if (Request.Params["logoupload"] != null) {
            string companynumber = Request.Params["companynumber"];
            string savePath = Server.MapPath("\\images") + "\\clients\\" + companynumber + "\\client.gif";
            if (File.Exists(savePath))
                File.Delete(savePath);
            //save the file to the server 
            Request.Files[0].SaveAs(savePath);

            Response.Write("OK");
            Response.Flush();
            Response.End();
          }
       }
}

【讨论】:

  • 这可能值得更新,因为 $("#uploadTrg").load(function () { 位现在已弃用。
【解决方案2】:

我会回答我的问题,我想我找到了解决方案。这些是我为实现目标所遵循的步骤:

  1. 使form的属性“target”指向“iframe”。
  2. 使用普通的 HTML 请求(不是异步/Ajax 请求)提交表单。
  3. 因为目标框架是 iframe ,所以不会刷新整个页面 - 只是 iframe。
  4. 一旦 iframe onload 事件发生(使用 Javascript 捕获该事件),然后执行您想要的操作,例如您可以发回请求以列出最近上传的文件信息。

最终代码如下所示:

    <!-- Attach a file -->

    <iframe id="uploadTrg" name="uploadTrg" height="0" width="0" frameborder="0" scrolling="yes"></iframe>

    <form id="myForm" action="http://example.com/file-upload-service" method="post" enctype="multipart/form-data"  target="uploadTrg">

        File: <input type="file" name="file">
        <input type="submit" value="Submit" id="submitBtn"/>

    </form>

    <div id="ajaxResultTest"></div>

javascript:

$("iframe").load(function(){
    // ok , now you know that the file is uploaded , you can do what you want , for example tell the user that the file is uploaded 
    alert("The file is uploaded");

    // or you can has your own technique to display the uploaded file name + id ? 
    $.post('http://example.com/file-upload-service?do=getLastFile',null,function(attachment){

       // add the last uploaded file , so the user can see the uploaded files
       $("#ajaxResultTest").append("<h4>" + attachment.name + ":" + attachment.id "</h4>");

    },'json');
});

【讨论】:

  • 目标属性已弃用 (w3schools.com/TAGS/att_form_target.asp)。我开始相信必须使用已弃用的 (X)HTML 或 Flash/等。完成/应该/非常原始的功能。
  • @iMatoria 你说得对,我删除了额外的代码,并试图进一步澄清答案。
  • @MikeS,我检查了 MDN,但没有看到它说 HTML 表单元素中的目标属性已被弃用。 MDN 是比 W3Schools 更可靠的资源,因此您可能误会了。这是链接:developer.mozilla.org/en-US/docs/Web/HTML/Element/form
  • @SpainTrain HTML5 支持 target 属性。 ;)
  • 很好的解释。但是,您可以在 iframe 内容中回显响应,然后在 js 中读取它,而不是制作另一个 ajax 帖子
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 2010-10-30
  • 2018-06-11
  • 2011-12-08
  • 1970-01-01
  • 2014-01-29
相关资源
最近更新 更多