3

我正在使用 Tomahawk inputFileUpload 组件来允许用户将文件上传到服务器。我通过在文件上传后检查文件大小并在文件太大时显示错误来实现“软”文件大小限制。但是,我还想要一个更大的“硬”​​限制,一旦超过限制,上传就会立即停止。例如,如果硬限制为 500MB,并且用户尝试上传 2GB 的文件,则上传将在 500MB 上传后立即停止并显示错误。

我曾希望使用 MyFaces ExtensionsFilter 并设置 uploadMaxFileSize 可以解决问题,但在引发 SizeLimitExceededException 之前文件已完全上传。

是否有可能做到这一点?理想情况下,我仍然可以使用 Tomahawk,但任何其他解决方案都会很好。

4

2 回答 2

9

Web 服务器不能中途中止 HTTP 请求然后返回 HTTP 响应。整个 HTTP 请求必须被完全消耗,直到最后一位才能返回 HTTP 响应。这就是 HTTP 和 TCP/IP 的本质。使用服务器端编程语言对它无能为力。

请注意,Tomahawk 文件上传大小限制已经考虑到服务器的内存/磁盘空间不会在达到大小限制时被整个上传的文件污染。

最好的办法是在上传之前在 JavaScript 中验证文件长度。这在支持HTML5 FileAPI 的浏览器中受支持。当前版本的 Firefox、Chrome、Safari、Opera 和 Android 都支持它。IE9还不支持,以后的IE10会支持。

<t:inputFileUpload ... onchange="checkFileSize(this)" />

像这样的东西

function checkFileSize(inputFile) {
    var max = 500 * 1024 * 1024; // 500MB

    if (inputFile.files && inputFile.files[0].size > max) {
        alert("File too large."); // Do your thing to handle the error.
        inputFile.value = null; // Clears the field.
    }
}
于 2012-05-09T01:47:50.847 回答
2

试试这个:

<div>
    <p:fileUpload id="fileUpload" name="fileUpload" value="#{controller.file}" mode="simple" rendered="true"/>
    <input type="button" value="Try it" onclick="checkFileSize('fileUpload')" />

</div>

当用户单击“尝试”按钮时,将调用 checkFileSize() 函数并验证 fileUpload primefaces 组件。如果文件大小大于 500MB,则不会上传文件。

<script>
    // <![CDATA[
        function checkFileSize(name) {
            var max = 500 * 1024 * 1024; // 500MB
            var inputFile = document.getElementsByName(name)[0];
            var inputFiles = inputFile.files; 

            if (inputFiles.lenght > 0 && inputFiles[0].size > max) {
                alert("File too large."); // Do your thing to handle the error.
                inputFile.value = null; // Clears the field.
            }
        }
    // ]]>
</script>

checkFileSize() 逻辑基于上面回答的BalusC 。

测试的版本:

素面3.5

JSF 2.1

于 2014-02-27T22:59:00.420 回答