使用jQuery,在上传文件之前限制文件大小

50

在PHP中,他们有一种方式可以在上传文件之后限制文件大小,但是在上传之前不能做到。我使用Malsup jQuery Form插件来进行表单提交,并且它支持图像文件上传。

我想知道是否有一种限制,可以设置通过AJAX流上传到服务器的字节数量?这将允许我检查文件大小并在文件过大时返回错误信息。

通过在客户端上执行此操作,这可以阻止那些尝试上传10MB Pentax拍摄的新手。

9个回答

49
这是我在一个非常相似的问题中的回答副本:如何使用jQuery检查文件输入大小?
实际上,您没有访问文件系统(例如读写本地文件)的权限。但是,由于HTML5文件API规范,您可以访问一些文件属性,其中文件大小就是其中之一。
对于以下HTML代码:
<input type="file" id="myFile" />

尝试以下操作:

//binds to onchange event of your input field
$('#myFile').bind('change', function() {
  //this.files[0].size gets the size of your file.
  alert(this.files[0].size);
});

由于它是HTML5规范的一部分,因此它仅适用于现代浏览器(IE需要v10),并且我在这里添加了更多关于其他文件信息的细节和链接,你应该知道:http://felipe.sabino.me/javascript/2012/01/30/javascipt-checking-the-file-size/


旧版浏览器支持

请注意,旧版本的浏览器将返回null值,因此访问this.files[0]将引发异常,你应该检查是否支持File API后再使用它。


5
@ShawnEary 这不是一个技巧,而只是HTML5文件API的实现,IE10确实支持http://caniuse.com/#feat=fileapi :) - Felipe Sabino

8

我认为除非使用Flash、ActiveX或Java上传程序,否则不可能实现。

出于安全原因,Ajax / JavaScript在上传期间无法访问文件流或文件属性。


9
在您编写这篇答案的时候,这实际上是正确的,但是现在我们在HTML5的新规范中有了一个文件API :) https://dev59.com/OHVC5IYBdhLWcg3wZwNT#9106313 - Felipe Sabino

6

我尝试了这种方式,结果在IE*和Mozilla 3.6.16中都可以得到,没有在旧版本中进行检查。

<img id="myImage" src="" style="display:none;"><br>
<button onclick="findSize();">Image Size</button>
<input type="file" id="loadfile" />
<input type="button" value="find size" onclick="findSize()" />
<script type="text/javascript">
function findSize() {
    if ( $.browser.msie ) {
       var a = document.getElementById('loadfile').value;
           $('#myImage').attr('src',a);
           var imgbytes = document.getElementById('myImage').size;
           var imgkbytes = Math.round(parseInt(imgbytes)/1024);
           alert(imgkbytes+' KB');
    }else {
           var fileInput = $("#loadfile")[0];
           var imgbytes = fileInput.files[0].fileSize; // Size returned in bytes.
           var imgkbytes = Math.round(parseInt(imgbytes)/1024);
                   alert(imgkbytes+' KB');
     }
}    
</script>

添加Jquery库。

首先,感谢您提供的代码。其次,我在这里有这段代码:http://jsfiddle.net/6ZQkj/2/ 在Mac上的Chrome、Firefox或Safari中无法运行,请提供任何见解。 - Doug Molineux

4
我遇到了同样的问题。您需要使用ActiveX或Flash(或Java)。好的是,它不必具有侵入性。我有一个简单的ActiveX方法,可以返回要上传文件的大小。
如果您选择Flash,甚至可以使用一些花哨的js/css来自定义上传体验 - 只使用Flash(作为1x1“电影”)来访问其文件上传功能。

这似乎是正确的方法,我相信Flickr使用Flash控件来提供有关上传内容的反馈,例如文件大小和上传进度。 - Tom
我们使用SWFUpload,虽然它已经不再处于活跃开发状态,但它已被证明非常方便和易于集成。 - Purefan

4
我发现Apache2(您可能还要检查Apache 1.5)有一种方法可以在上传之前通过在您的.htaccess文件中添加以下内容来限制此项:

LimitRequestBody 2097152

这将限制文件上传为2兆字节(2 * 1024 * 1024)(如果我正确计算了字节数)。

请注意,当您在表单提交或获取请求上超过此限制时,Apache错误日志将生成此条目:

Requested content-length of 4000107 is larger than the configured limit of 2097152

同时它还会在网页浏览器中显示此消息:
<h1>Request Entity Too Large</h1>

如果你正在使用像Malsup jQuery表单插件这样的东西进行AJAX表单提交,你可以像这样捕获H1响应并显示错误结果。

顺便说一下,返回的错误号是413。因此,你可以在你的.htaccess文件中使用一个指令,例如...

Redirect 413 413.html

...并提供一个更优雅的错误结果返回。


7
是的,但用户仍需等待他们的30MB文件上传完毕才能收到错误提示。如果使用Flash/ActiveX,你可以在他们提交页面之前就警告他们。 - EndangeredMassa

4
 $(".jq_fileUploader").change(function () {
    var fileSize = this.files[0];
    var sizeInMb = fileSize.size/1024;
    var sizeLimit= 1024*10;
    if (sizeInMb > sizeLimit) {


    }
    else {


    }
  });

3
这个问题相当古老了,你有足够的时间来写一个出色的描述性答案,即请在你的代码中添加一些解释。 - Ilya Luzyanin
我认为它在IE 9上不起作用,文件对象没有大小属性。 - Stiger

3
请尝试以下代码:
var sizeInKB = input.files[0].size/1024; //Normally files are in bytes but for KB divide by 1024 and so on
var sizeLimit= 30;

if (sizeInKB >= sizeLimit) {
    alert("Max file size 30KB");
    return false;
}

2

像其他人所说,仅使用JavaScript是不可能的,因为这种方式存在安全模型。

如果您能够,我建议使用以下其中一个解决方案...两者都使用Flash组件进行客户端验证;但是,它们都使用JavaScript / jQuery进行连接。 两者都非常好用,并且可以与任何服务器端技术一起使用。

http://www.uploadify.com/

http://swfupload.org/


0

客户端无法验证图像大小、宽度或高度。您需要将此文件上传到服务器并使用 PHP 验证所有这些信息。 PHP 有特殊的函数,如:getimagesize()

list($width, $height, $type, $attr) = getimagesize("img/flag.jpg");
echo "<img src=\"img/flag.jpg\" $attr alt=\"getimagesize() example\" />";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接