【问题标题】:jQuery upload file using jQuery's ajax method (without plugins)jQuery上传文件使用jQuery的ajax方法(无插件)
【发布时间】:2011-02-05 04:26:32
【问题描述】:

现在我想实现图片上传,不使用任何插件。

我的上传表单是这样的

<form action="/Member/UploadPicture" enctype="multipart/form-data" id="uploadform" method="post">
            <span>
                <div class="upload" id="imgUpl">
                    <h3>Upload profile picture</h3>
                    <div class="clear5"></div>
                    <input  type="file" name="file" id="file"  />
                    <button class="btn-bl"  id="upComplete"><span>Upload</span></button>
                </div>

            </span>
            </form>

我的 jQuery 代码是:

  $('#upComplete').click(function () {
            $('#up').hide();
            $('#upRes').show();

            var form = $("#uploadform");

            $.ajax({
                type: "POST",
                url: "/Member/UploadPicture",
                data: form.serialize(),
                success: function (data) {
                    alert(data);
                }
            });

            $.fancybox.close();
            return false;
        });

如果我打开 firebug,我可以看到 ajax() 方法执行简单的表单发布(不是多部分)并且 POST 内容为空

是否可以使用 jQuery ajax() 方法上传文件,或者我应该以其他方式上传文件吗?

非常感谢

【问题讨论】:

    标签: jquery asp.net-mvc ajax upload


    【解决方案1】:

    jQuery ajax 不支持文件上传,手动实现这一点可能很麻烦。我建议您查看 jQuery form 插件。

    当然,如果您不想包含它,您可以随时查看插件的源代码以了解它是如何实现的(它使用隐藏的 iFrame,因为文件无法使用 AJAX 上传)但是为什么要这样做你可以直接使用它:-)

    以下是您的代码的示例:

    $(function() {
        $('#uploadform').ajaxForm();
    });
    

    还将上传按钮设为提交按钮:

    <button class="btn-bl" id="upComplete" type="submit">
        <span>Upload</span>
    </button>
    

    【讨论】:

      【解决方案2】:

      AJAX 或更恰当的 XMLHttpRequest 尚不支持文件上传。有一些解决方法,例如通过&lt;iframe&gt; 上传,但它相当麻烦。您的时间将更好地用于构建您的应用程序,而不是重新发明这些解决方案。

      但是,如果您对它的内部工作方式感到好奇,请随时查看提供此功能的一些插件的源代码。可以在此链接找到一个非常简单的解释 - http://www.openjs.com/articles/ajax/ajax_file_upload/

      基本上,您将表单 target 更改为在 &lt;iframe&gt; 内提交,从而避免页面刷新,并模拟 AJAX,这不是真的,但谁在乎 - 最终用户无法分辨。

      基于 iframe 的上传的最小示例可能如下所示:

      ​$("#upComplete").click(function() {
          // create a dynamic iframe, or use existing one 
          var iframe = $("<iframe id='f' name='f' src=''>");
          // attach a load event to handle response/ know about completion
          iframe.load(function() { alert('complete'); });
          iframe.appendTo('body');
          // change form's target to the iframe (this is what simulates ajax)
          $('#uploadForm').attr('target', 'f');
          $('#uploadForm').submit();
      });​​​​​​
      

      请注意,这不会做任何响应处理,只是将图片发送到服务器。要处理响应,必须为 iframe 的 load 事件编写回调。

      【讨论】:

        【解决方案3】:

        其实有一种方法可以使用 Firefox>3 和 Chrome 上传 ajax (xmlhttp) 文件,也可以不使用表单和 iframe 上传多个文件。实际上,我正在为此制作一个 jQuery 插件,很快我将发布它。这是一个简单的例子:

        var file=$('<input type=file />').get(0).files[0];
        function asyncupload(file)
        {
            var xhr = new XMLHttpRequest();    
            xhr.onreadystatechange = function() 
            {  
                if (xhr.readyState == 4) 
                {  
                    if ((xhr.status >= 200 && xhr.status <= 200) || xhr.status == 304) 
                    {  
                        //alert(xhr.responseText);
                    }  
                }  
            };  
            xhr.upload.onload=function(e)
            {
                $('div#axprogress').progressbar("option", "value", 100);;
            };  
            xhr.upload.onprogress=function(e) 
            {  
                if (e.lengthComputable) 
                {  
                    var perc = Math.round((e.loaded * 100) / e.total);  
                    $('div#axprogress').progressbar("option", "value", perc);
                }  
            };  
        
            xhr.open("POST", "upload.php?filename="+file.name,true);  
            xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
            xhr.setRequestHeader("X-File-Name", encodeURIComponent(file.name));
            xhr.send(file);  
            return xhr;
        }
        

        要在服务器端获取文件,如php,必须为upload.php执行此操作:

        $input = fopen("php://input", "r");
        $temp = tmpfile();
        $realSize = stream_copy_to_stream($input, $temp);
        fclose($input);
        
        if ($realSize != $this->getSize())
            {            
            return false;
        }
        
        $target = fopen($_GET['filename'], "w");        
        fseek($temp, 0, SEEK_SET);
        stream_copy_to_stream($temp, $target);
        fclose($target); 
        

        这是一个简单的想法示例,不是完整的工作脚本。希望这可以帮助。更多信息请参考https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

        【讨论】:

          【解决方案4】:

          虽然您可以自己创建一个 multipart/form-data 请求正文以包含文件上传字段,但这对您没有帮助,因为您无法从文件上传字段中读取客户端文件。

          (除了使用FileList接口,但目前只有Firefox支持。)

          【讨论】:

          • +1 表示FileList。关于通过将文件拖放到窗口来完成文件上传的时间。
          【解决方案5】:
             <input type="file" id="picfile" name="picf" />
                 <input type="text" id="txtName" style="width: 144px;" />
            <input type="button" value=" ADD " id="btncatsave" style="width: 75px" />
           $("#btncatsave").click(function () {
          var Name = $("#txtName").val();
          var formData = new FormData();
          var totalFiles = document.getElementById("picfile").files.length;
          
                              var file = document.getElementById("picfile").files[0];
                              formData.append("FileUpload", file);
                              formData.append("Name", Name);
          
          $.ajax({
                              type: "POST",
                              url: '/Category_Subcategory/Save_Category',
                              data: formData,
                              dataType: 'json',
                              contentType: false,
                              processData: false,
                              success: function (msg) {
          
                                           alert(msg);
          
                              },
                              error: function (error) {
                                  alert("errror");
                              }
                          });
          
          });
          
           [HttpPost]
              public ActionResult Save_Category()
              {
                string Name=Request.Form[1]; 
                if (Request.Files.Count > 0)
                  {
                      HttpPostedFileBase file = Request.Files[0];
                   }
          
          
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-08-23
            • 2013-03-21
            • 1970-01-01
            • 2013-08-28
            • 1970-01-01
            • 2013-01-28
            • 2013-03-04
            相关资源
            最近更新 更多