413 Request Entity Too Large这个报错,多数人第一反应是去改php.ini。改完重启,上传还是失败,报错一模一样。原因是这个状态码根本不是PHP发出来的。nginx在收请求体的时候就把连接掐了,请求还没走到PHP那一层。所以先看这个413是谁返回的,比改哪个参数重要得多。响应头里Server是nginx,错误日志里有一行client intended to send too large body,就说明卡在nginx这一层。如果响应头里没有Server,页面是PHP自己的报错样式,那就是另一回事,先去看PHP的错误日志。定位清楚再动手,否则只是在几个配置里轮着试。
nginx这边管大小的是client_max_body_size,默认1m。也就是超过一兆的请求体,直接挡在门外,连解释的机会都不给。这个参数可以写在http、server、location三层,就近生效。写在server层最省事,整个站点一起放开。
PHP这边有两道。upload_max_filesize管单个文件,默认2M。post_max_size管整个表单,默认8M。后者必须大于等于前者,否则文件没超单个上限,整个请求先被卡住了。这两个值还受内存限制。post_max_size设到几百兆,PHP的内存上限也要跟着调,不然解析表单的时候先崩。
两个都改完还有一层:执行时间。max_execution_time默认30秒。大文件传到一半被中断,页面空白,日志里连413都没有。这种情况页面通常返回空白,或者干脆502,很容易被当成别的问题。前端有进度条的,能看到进度卡在某个百分比不动。
分界其实很好认。浏览器立刻返回413页面,是nginx挡的。表单提交后页面正常打开,但文件列表里没有,或者$_FILES里的error等于1,是PHP挡的。前者改nginx配置,后者改php.ini。两边都改了还失败,去看上传目录的权限和剩余空间。权限问题报的是另一个错,但表现同样是传不上去,跟大小限制很容易混在一起。
nginx改完用reload,不是restart。php.ini改完要reload php-fpm。光改文件不生效,这点最容易漏,改完以为成功了,测试还是老样子。确认生效的办法是看phpinfo里那两项的值。命令行用php -i查到的可能不是同一个ini文件,别拿它当准。
还有个容易忽略的:反向代理后面不止一层。CDN有自己的请求体上限,前置nginx也有。前面那层不放开,后面的配置全是白改。CDN的请求体上限在控制台的规则配置里,各家叫法不同,找请求大小或者body相关的项。
改的时候按顺序对:CDN、反代、nginx、PHP。哪一层没放开,表现都是上传失败,从现象上看不出来区别。从上往下逐层放开,每改一层测一次,能很快定位到还卡在哪一层。传一个刚好超限的文件试一次。看错误日志是哪一层先报,日志比配置表更可靠。配置写对了但位置放错,照样不生效。测完把上限调到刚好够用的值,别图省事直接设成不限制。
A5创业网 版权所有