Docker, Nginx。 PHP-fpm 上传进度条不工作
Docker, Nginx. PHP-fpm Upload progress bar not work
我使用 docker-compose (php 7.2 FROM phpdockerio/php72-fpm:latest )
services:
webserver:
image: nginx:alpine
nginx.con
user nginx;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main;
#sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 80 default;
client_max_body_size 208M;
access_log /var/log/nginx/application.access.log;
root /application/public;
rewrite ^/index\.php/?(.*)$ / permanent;
try_files $uri @rewriteapp;
location @rewriteapp {
rewrite ^(.*)$ /index.php/ last;
}
# Deny all . files
location ~ /\. {
deny all;
}
location ~ ^/(index)\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_index app_dev.php;
send_timeout 1800;
fastcgi_read_timeout 1800;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}
# Statics
location /(bundles|media) {
access_log off;
expires 30d;
try_files $uri @rewriteapp;
}}
}
我创建测试控制器来更新进度条
/**
* @Route("/progressTest", name="progressTest")
* @param Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function progressAction(){
ob_start();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$total = 10;
for($i=0;$i<$total;$i++)
{
$percent = intval($i/$total * 100)."%";
sleep(1); // Here call your time taking function like sending bulk sms etc.
echo '<script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:'.$percent.';background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">'.$percent.' is processed.</div>";
</script>';
ob_flush();
flush();
}
echo '<script>parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">Process completed</div>"</script>';
return new Response('OK '.$i);
}
运行 它在模板中
<div class="col-md-12">
<div id="progressbar" style="border:1px solid #ccc; border-radius: 5px; "></div>
<div id="information" style="border:1px solid #ccc; border-radius: 5px; "></div>
</div>
<iframe name="loadarea" src="{{ path("progressTest") }}" id="loadarea" style="display:none2;"></iframe><br />
但有待循环结束,然后得到
<script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:0%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">0% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:10%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">10% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:20%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">20% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:30%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">30% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:40%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">40% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:50%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">50% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:60%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">60% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:70%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">70% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:80%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">80% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:90%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">90% is processed.</div>";
</script><script>parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">Process completed</div>"</script>OK 10
如何更新进度条?
您很可能遗漏了官方文档的 header X-Accel-Buffering
, as described in Streaming a Response 部分。基本上,你的 FPM 不会缓冲任何东西,但 NGINX 会缓冲任何东西,所以最后你会得到所有东西。
尝试将 header 设置为 no
,看看它是否有帮助。
附带说明一下,像这样返回 <script>
标签就像 运行 把剪刀。我建议您完全重构它,让客户端仅根据百分比进行图形操作。
我使用 docker-compose (php 7.2 FROM phpdockerio/php72-fpm:latest )
services:
webserver:
image: nginx:alpine
nginx.con
user nginx;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main;
#sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 80 default;
client_max_body_size 208M;
access_log /var/log/nginx/application.access.log;
root /application/public;
rewrite ^/index\.php/?(.*)$ / permanent;
try_files $uri @rewriteapp;
location @rewriteapp {
rewrite ^(.*)$ /index.php/ last;
}
# Deny all . files
location ~ /\. {
deny all;
}
location ~ ^/(index)\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_index app_dev.php;
send_timeout 1800;
fastcgi_read_timeout 1800;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}
# Statics
location /(bundles|media) {
access_log off;
expires 30d;
try_files $uri @rewriteapp;
}}
}
我创建测试控制器来更新进度条
/**
* @Route("/progressTest", name="progressTest")
* @param Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function progressAction(){
ob_start();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$total = 10;
for($i=0;$i<$total;$i++)
{
$percent = intval($i/$total * 100)."%";
sleep(1); // Here call your time taking function like sending bulk sms etc.
echo '<script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:'.$percent.';background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">'.$percent.' is processed.</div>";
</script>';
ob_flush();
flush();
}
echo '<script>parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">Process completed</div>"</script>';
return new Response('OK '.$i);
}
运行 它在模板中
<div class="col-md-12">
<div id="progressbar" style="border:1px solid #ccc; border-radius: 5px; "></div>
<div id="information" style="border:1px solid #ccc; border-radius: 5px; "></div>
</div>
<iframe name="loadarea" src="{{ path("progressTest") }}" id="loadarea" style="display:none2;"></iframe><br />
但有待循环结束,然后得到
<script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:0%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">0% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:10%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">10% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:20%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">20% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:30%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">30% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:40%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">40% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:50%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">50% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:60%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">60% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:70%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">70% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:80%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">80% is processed.</div>";
</script><script>
parent.document.getElementById("progressbar").innerHTML="<div style=\"width:90%;background:linear-gradient(to bottom, rgba(125,126,125,1) 0%,rgba(14,14,14,1) 100%); ;height:35px;\"> </div>";
parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">90% is processed.</div>";
</script><script>parent.document.getElementById("information").innerHTML="<div style=\"text-align:center; font-weight:bold\">Process completed</div>"</script>OK 10
如何更新进度条?
您很可能遗漏了官方文档的 header X-Accel-Buffering
, as described in Streaming a Response 部分。基本上,你的 FPM 不会缓冲任何东西,但 NGINX 会缓冲任何东西,所以最后你会得到所有东西。
尝试将 header 设置为 no
,看看它是否有帮助。
附带说明一下,像这样返回 <script>
标签就像 运行 把剪刀。我建议您完全重构它,让客户端仅根据百分比进行图形操作。