如何异步上传文件?

坚强是说给别人听的谎言 提交于 2019-12-03 18:12:15

我想用jQuery异步上传文件。 这是我的HTML:

<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

这是我的jQuery代码:

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});

我只获取文件名,而不是上传文件。 我该怎么做才能解决此问题?


#1楼

我已经在Rails环境中编写了此代码 。 如果您使用轻量级的jQuery-form插件,则仅包含五行JavaScript。

挑战在于如何使AJAX上传工作,因为标准remote_form_for无法理解多部分表单提交。 它不会发送Rails随AJAX请求返回的文件数据。

这就是jQuery-form插件起作用的地方。

这是它的Rails代码:

<% remote_form_for(:image_form, 
                   :url => { :controller => "blogs", :action => :create_asset }, 
                   :html => { :method => :post, 
                              :id => 'uploadForm', :multipart => true }) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

以下是相关的JavaScript:

$('#uploadForm input').change(function(){
 $(this).parent().ajaxSubmit({
  beforeSubmit: function(a,f,o) {
   o.dataType = 'json';
  },
  complete: function(XMLHttpRequest, textStatus) {
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  },
 });
});

这是Rails控制器的动作,非常漂亮:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

在过去的几周里,我一直在Bloggity上使用它,它的工作原理像冠军。


#2楼

我一直在使用下面的脚本上传图像,但效果很好。

的HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

的JavaScript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

说明

我使用response div来显示上传动画和上传完成后的响应。

最好的部分是,使用此脚本时,您可以随文件发送额外的数据,例如ids等。 我已经提到了脚本中的extra-data

在PHP级别,这将像正常文件上传一样工作。 可以将多余数据作为$_POST数据进行检索。

在这里,您没有使用插件和东西。 您可以根据需要更改代码。 您在这里不是盲目编码。 这是任何jQuery文件上传的核心功能。 其实是Javascript。


#3楼

您可以非常轻松地在原始JavaScript中完成此操作。 这是我当前项目的摘录:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);

#4楼

注意:此答案已过时,现在可以使用XHR上传文件。


您不能使用XMLHttpRequest (Ajax)上传文件。 您可以使用iframe或Flash模拟效果。 出色的jQuery表单插件 ,可通过iframe发布文件以获得效果。


#5楼

2019更新:它仍然取决于您的人口统计使用的浏览器。

使用“新” HTML5 file API时要了解的重要一点是, 直到IE 10才支持它。 如果您要针对的特定市场对旧版本Windows的倾向高于平均水平,则可能无法使用它。

截至2017年,大约5%的浏览器是IE 6、7、8或9之一。如果您进入一家大公司(例如,这是B2B工具,或者您要提供培训的内容),那么这个数字可能会飙升。 2016年,我与一家在其60%以上的计算机上使用IE8的公司打交道。

截至本次编辑的2019年,距离我最初的回答差不多11年了。 IE9及更低版本在全球范围内均在1%左右,但仍存在使用率更高的集群。

最重要的外卖从这个-whatever的特征-是, 请检查您的用户使用的浏览器 。 如果不这样做,您将学到一个快速而痛苦的课程,以了解为什么“为我工作”在交付给客户的产品中不够好。 caniuse是一个有用的工具,但请注意他们从哪里获得人口统计信息。 它们可能与您的不一致。 这从未比企业环境更真实。

我在2008年的回答如下。


但是,有可行的非JS文件上传方法。 您可以在页面上创建一个iframe(使用CSS隐藏该iframe),然后将表单定位为发布到该iframe。 主页不需要移动。

这是一个“真实”的帖子,因此并非完全互动。 如果您需要状态,则需要服务器端进行处理。 具体取决于您的服务器。 ASP.NET具有更好的机制。 PHP普通失败,但是您可以使用Perl或Apache修改来解决它。

如果您需要多个文件上传,则最好一次执行一个文件(以克服最大文件上传限制)。 将第一个表单发布到iframe中,使用上述方法监视进度,完成后,将第二个表单发布到iframe中,依此类推。

或使用Java / Flash解决方案。 他们可以更灵活地处理自己的帖子...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!