使用ajax的streaming方式配合php的flush分块输出需要注意的地方

【背景】
ajax的Streaming方式是一种单向的push方式,与传统http输出不同的时,它是分块输出的,这样可以在一个较长的请求中随时向浏览器push一些内容。
之前我写过一个博客是介绍使用ajax的Streaming方式获取内容的,地址:http://www.queyang.com/blog/archives/510

【应用场景】
假设有一个ajax请求需要执行几十秒甚至几分钟,通常只有等待全部执行完毕才会得到结果,假如我们希望能够实时的看到程序的执行状态,比如进度,某个节点的错误或成功信息等,此时就可以利用此技术,做到实时观察程序运行状态。

【服务器程序】
对于PHP来说,支持这种分块输出是非常简单的,只要输出类似以下代码即可:

<?php
// 先输出1024长度内容,避免firefox等不识别
echo str_pad('', 1024), "\r\n";
flush();   // 将内容推送到浏览器

for($i=0; $i<10; $i++)
{
    echo 'step:'.$i.' time:'.time();
    flush();  //推送数据
    sleep(1);
}

但是如果用nginx做代理的话,需要注意把 proxy_buffering 设置成 off,nginx默认是开启的。
这个参数的具体说明地址在 http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering
它的用途是开启缓冲区,如果开启缓冲区则会导致请求在结束时才会一次性推送给浏览器,这样就达不到预想的效果了。

另外,需要说明的是,在MyQEE里默认是有缓冲区的,所以如果要使用flush实时把数据推送到浏览器,还需要把MyQEE的缓冲区关闭,关闭方法,在页面输出内容之前加入以下代码(只需运行一次即可):

Core::close_buffers(false);