jQuery 上传进度和 AJAX 文件上传

Posted

技术标签:

【中文标题】jQuery 上传进度和 AJAX 文件上传【英文标题】:jQuery Upload Progress and AJAX file upload 【发布时间】:2011-06-18 22:04:45 【问题描述】:

我似乎没有清楚地表达我的问题。我需要发送一个文件(使用 AJAX),我需要使用nginx HttpUploadProgressModule 获取文件的上传进度。我需要一个好的解决方案来解决这个问题。我曾尝试使用 jquery.uploadprogress 插件,但我发现自己必须重写大部分内容才能使其在所有浏览器中工作并使用 AJAX 发送文件。

我只需要执行此操作的代码,它需要在所有主要浏览器(Chrome、Safari、FireFox 和 IE)中工作。如果我能得到一个可以处理多个文件上传的解决方案,那就更好了。

我正在使用jquery.uploadprogress plugin 从 NginxHttpUploadProgressModule 获取文件的上传进度。这是在 facebook 应用程序的 iframe 中。它在 Firefox 中工作,但在 chrome/safari 中失败。

当我打开控制台时,我得到了这个。

Uncaught ReferenceError: progressFrame is not defined
jquery.uploadprogress.js:80

知道如何解决这个问题吗?

我还想在文件完成后使用 AJAX 发送文件。我将如何实现它?

编辑: 我很快就需要这个,这很重要,所以我将在这个问题上悬赏 100 分。第一个回答的人将获得 100 分。

编辑 2: Jake33 帮我解决了第一个问题。第一个回答如何使用 ajax 发送文件的人也将获得 100 分。

【问题讨论】:

我看到它使用浏览器嗅探来检测 Safari(浏览器嗅探通常是不受欢迎的),所以 progressFrame 仅与 Safari/Chrome 一起使用(我不知道为什么)。发生错误的部分似乎是脚本试图引用 progressFrame 的地方,只是通过在全局范围内查找其名称而不是使用像 document.getElementsByName 这样的函数。 我不知道你说的“完成后使用AJAX发送”是什么意思——进度条不代表提交的进度吗?这不是说一旦完成就已经发送了吗?您的意思是希望原始表单提交由 AJAX 驱动,这样之后不会导致页面刷新? 是的。是的,但它的作用类似于表单提交。这正是我想要的。 如果问题是如何使用 jQuery 通过 XMLHttpRequest 通过 HTTP POST 发送数据,那么有jQuery.post 下面的答案对你有用吗?如果没有,您能否评论答案。由于所有的编辑,我有点困惑,并想尝试解决您的问题。谢谢。顺便说一句,我包含了 JQuery 的多文件上传插件的链接。 【参考方案1】:

如今,实际上可以使用 AJAX 上传文件。是的,AJAX,而不是像 swf 或 java 这样的蹩脚的 AJAX 崇拜者。

这个例子可能会对你有所帮助:https://webblocks.nl/tests/ajax/file-drag-drop.html

(它还包括拖放界面,但很容易被忽略。)

基本上是这样的:

<input id="files" type="file" />

<script>
document.getElementById('files').addEventListener('change', function(e) 
    var file = this.files[0];
    var xhr = new XMLHttpRequest();
    (xhr.upload || xhr).addEventListener('progress', function(e) 
        var done = e.position || e.loaded
        var total = e.totalSize || e.total;
        console.log('xhr progress: ' + Math.round(done/total*100) + '%');
    );
    xhr.addEventListener('load', function(e) 
        console.log('xhr upload complete', e, this.responseText);
    );
    xhr.open('post', '/URL-HERE', true);
    xhr.send(file);
);
</script>

(演示:http://jsfiddle.net/rudiedirkx/jzxmro8r/)

所以基本上它归结为这个 =)

xhr.send(file);

fileBlob 的类型:http://www.w3.org/TR/FileAPI/

另一种(更好的 IMO)方法是使用 FormData。这允许您 1) 为文件命名,例如在表单中;以及 2) 发送其他内容(也包括文件),例如在表单中。

var fd = new FormData;
fd.append('photo1', file);
fd.append('photo2', file2);
fd.append('other_data', 'foo bar');
xhr.send(fd);

FormData 使服务器代码更简洁,更向后兼容(因为请求现在具有与普通格式完全相同的格式)。

所有这些都不是实验性的,而是非常现代的。 Chrome 8+ 和 Firefox 4+ 知道该怎么做,但我不知道其他的。

这就是我在 php 中处理请求的方式(每个请求 1 个图像):

if ( isset($_FILES['file']) ) 
    $filename = basename($_FILES['file']['name']);
    $error = true;

    // Only upload if on my home win dev machine
    if ( isset($_SERVER['WINDIR']) ) 
        $path = 'uploads/'.$filename;
        $error = !move_uploaded_file($_FILES['file']['tmp_name'], $path);
    

    $rsp = array(
        'error' => $error, // Used in JS
        'filename' => $filename,
        'filepath' => '/tests/uploads/' . $filename, // Web accessible
    );
    echo json_encode($rsp);
    exit;

【讨论】:

这是一个仅在 XMLHttpRequest2 中可用的功能,完整的兼容性列表 - 看看caniuse.com/xhr2 @Rudie 你有 hotblocks.nl 教程链接吗?不仅仅是演示感谢广告 没有教程。从来没有写过。甚至没有将演示公开。 @NeilMartin 我已将 PHP 示例代码添加到答案的末尾。显然你会想用它做点别的事情。 我不确定我是否了解如何进行这项工作?如果你能在某个地方制作一个完整的工作示例并在线演示,我会很棒。或者关于如何使其工作以及正在做什么的一些指导?【参考方案2】:

以下是使用 AJAX 上传文件的一些选项:

AjaxFileUpload - 页面上需要一个表单元素,但上传文件而不重新加载页面。请参阅Demo。

List of JQuery Plug-ins Tagged With "File"

Uploadify - 一种基于 Flash 的文件上传方法。

How can I upload files asynchronously?

Ten Examples of AJAX File Upload - 这是今年发布的。

更新:这是Multiple File Uploading的JQuery插件。

【讨论】:

我在几个项目中成功使用了plUpload(多文件上传有进度,支持Flash/Html5/Silverlight等) AjaxFileUpload 是一坨屎。它与 1.5 以后的任何 jquery 版本都不兼容。代码也很丑陋。 @Adam - 很高兴知道。我想一年会有很多变化。我们的头发变得有点白了,javascript 库停止使用更新的软件版本...... 扩展@Adam,在ie9+上AjaxFileUpload中断 @RanaMuhammadUsman - 现在再看看。我相信我找到了移动插件的位置。希望这会有所帮助。

以上是关于jQuery 上传进度和 AJAX 文件上传的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 上传进度和 AJAX 文件上传

jQuery 上传进度和 AJAX 文件上传

jQuery 上传进度和 AJAX 文件上传

jQuery 上传进度和 AJAX 文件上传

显示多文件上传 Jquery/Ajax 的进度

jquery ajax实现上传文件代码,带进度条