Javascript 我如何中止超过php最大上传量的文件上传?
当上传超过PHP设置允许的最大大小的文件时,通常会在我能够处理服务器端的响应之前上传整个文件 在php.ini中,我将最大帖子大小和最大上传大小设置为2MB。当我在上载表单中选择一个超过2MB的文件(也称为1GB文件)时,服务器仍会接受该文件,但我需要等待整个文件上载完毕,以便处理上载事件 现在,有趣的是,上传进度会话返回100%,允许我返回上传表单隐藏进度条的控制,再次显示上传表单和提交按钮,但是由于必须等待上传实际完成,我无法将响应返回给用户 对于我的项目,有3个部分: 上载表单-包含将上载发布到“upload.php”隐藏iframe的代码,并在“upload\u progress.php”XHR上监视进度。 upload.php-这是负责接受文件的文件处理程序,然后根据文件类型、错误、成功等将响应提升回上载表单锁定到当前域和协议的跨帧脚本。 upload_progress.php-这只是读取php的uploadprogress模块提供的上传进度的会话数据。响应是一个整数。 问题是,如果上载太大,3将显示为已完成,而2将继续接受数据,直到整个文件上载完毕 我想知道的是,当它发生时,有没有任何方法可以立即检测到它,而不是100%依赖于JavaScript在上传之前检查文件大小,因为这可以绕过。我知道我可以在发送文件之前检查客户端,但是在javascript中实现客户端中止之前,如果文件太大,我希望实现适当的服务器端中止上传。也就是说,我不想依靠JavaScript来实现服务器安全文件类型、大小等 希望我把一切都解释清楚了。我已经在PHP中看到这个问题很多年了,当接收到的数据超过PHP.ini中设置的限制时,我很惊讶文件上传没有在服务器端自动中止 如果有不同,下面是我的PHP版本详细信息Javascript 我如何中止超过php最大上传量的文件上传?,javascript,php,ajax,file-upload,upload,Javascript,Php,Ajax,File Upload,Upload,当上传超过PHP设置允许的最大大小的文件时,通常会在我能够处理服务器端的响应之前上传整个文件 在php.ini中,我将最大帖子大小和最大上传大小设置为2MB。当我在上载表单中选择一个超过2MB的文件(也称为1GB文件)时,服务器仍会接受该文件,但我需要等待整个文件上载完毕,以便处理上载事件 现在,有趣的是,上传进度会话返回100%,允许我返回上传表单隐藏进度条的控制,再次显示上传表单和提交按钮,但是由于必须等待上传实际完成,我无法将响应返回给用户 对于我的项目,有3个部分: 上载表单-包含将上载
PHP 5.6.17-0+deb8u1 (cli) (built: Jan 13 2016 09:10:12)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
PHP FPM在我的apache配置中为PHP服务的是什么
PHP 5.6.17-0+deb8u1 (fpm-fcgi) (built: Jan 13 2016 09:10:13)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with the ionCube PHP Loader (enabled) + Intrusion Protection from ioncube24.com (unconfigured) v5.0.23, Copyright (c) 2002-2016, by ionCube Ltd.
with Xdebug v2.3.3, Copyright (c) 2002-2015, by Derick Rethans
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
和Apache
Server version: Apache/2.4.10 (Debian)
Server built: Nov 28 2015 14:05:48
Server's Module Magic Number: 20120211:37
Server loaded: APR 1.5.1, APR-UTIL 1.5.4
Compiled using: APR 1.5.1, APR-UTIL 1.5.4
Architecture: 64-bit
Server MPM: prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/etc/apache2"
-D SUEXEC_BIN="/usr/lib/apache2/suexec"
-D DEFAULT_PIDLOG="/var/run/apache2.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="mime.types"
-D SERVER_CONFIG_FILE="apache2.conf"
使用Javascript并在上传文件之前检查文件大小,尽管这不是如何从服务器端中止mid上传的示例 下面是一个活生生的例子: JS在这里:
document.forms[0].addEventListener('submit', function( evt ) {
var file = document.getElementById('file').files[0];
// 1 MB = 1048576 this size is in bytes
if(file && file.size < 2097152) { // 2MB = 2097152
//Submit form
document.getElementById('message').innerHTML = 'The File '+bytesToSize(file.size)+' is OK!';
}
else
{
//Prevent default and display error
document.getElementById('message').innerHTML = 'The File '+bytesToSize(file.size)+' is to big!';
evt.preventDefault();
}
}, false);
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return '0 Bytes';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}
您确定在点击php upload_max_filesize之前上传了整个文件吗?web服务器将上传传递到PHP应用程序,PHP在处理上传之前不知道文件大小。是的,我100%确定。等待时间与文件传输持续时间成正比。例如,在我的网络上,1GB大约需要20分钟,之后,我会从upload.php脚本得到响应,但不是在之前。-但是我不知道它要去哪里。我认为只是在内存中,但不知道。我相信这可以通过一个简单的上传表单相当容易地复制,没有什么像modsec/etc那样会干扰本机上传操作。如果你说的是真的,那么这将是一个毫无意义的限制,所以我无法想象这会是一个PHP问题,web服务器可能正在对其进行缓冲,直到将其传递给PHP。您的web服务器设置是什么web服务器发行版、版本、PHP API在我的问题中添加了web服务器详细信息和PHP版本。我实际上使用的是php5 fpm,但是版本和编译是相同的,配置在重要的地方是相同的。谢谢你的回答,但是我已经熟悉如何使用JavaScript进行这些检查。这并不能阻止攻击者直接将文件推送到表单中,也就是说,如果接收的数据超过X数量,服务器端需要实际工作并停止数据上传。正如我在文章中所说,上传进度会得到通知,但是服务器会继续接收文件,直到文件完成后才返回控制。您还可以在Flash/Java/etc中检查上载大小/etc。仅依靠客户端来确保满足限制是一个劣质的解决方案。请不要误会,您提供的是非常好的客户端验证,假设启用了JavaScript,并且没有强制进行攻击。试想一下,表单上发生了一次不错的DoS攻击,仅使用100个客户端将1GB垃圾数据上传到100MB服务器连接,最大速度约为20 MB/秒。由于服务器仍将接受整个文件,您可以看到它如何很容易地耗尽带宽/etc,而且速度非常快。
document.forms[0].addEventListener('submit', function( evt ) {
var file = document.getElementById('file').files[0];
// 1 MB = 1048576 this size is in bytes
if(file && file.size < 2097152) { // 2MB = 2097152
//Submit form
document.getElementById('message').innerHTML = 'The File '+bytesToSize(file.size)+' is OK!';
}
else
{
//Prevent default and display error
document.getElementById('message').innerHTML = 'The File '+bytesToSize(file.size)+' is to big!';
evt.preventDefault();
}
}, false);
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return '0 Bytes';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}