在正常情况下,如果一个页面需要进行部分数据更新操作,只需要发送一个异步请求到服务器,而后接受服务器返回的数据。但是有些业务可能需要由服务器推送数据给客户端,此类业务该如何实现呢?这类业务一般可以使用websocket或者反向ajax。 G( u- z/ R9 N) ]/ l- q
websocket:
. e! _4 H) {6 D( |# I: ?" u( \websocket不必多说,他是一个长连接,可双向数据通信。但是成本比较高,适合做即使通讯。
, O/ x" w4 b) x) k# J# K反向ajax:
/ o6 J2 l' J" p" M: e! N9 g反向ajax是指客户端不必从服务器获取信息,服务器会把相关信息直接推送到客户端。在一个标准的HTTP Ajax请求中,数据是发送给服务器端的,而反向Ajax可用某些特定的方式来模拟发出一个Ajax请求,让服务器尽可能快地向客户端发送事件。
! g- j* r. |- q: q' y2 C, O% D8 W* J反向ajax后端PHP具体实现代码:
5 c5 r$ X/ O" l/ G& Z. U& x; N/ |在PHP中实现反向ajax需要使用ob缓存,通过不断的输出ob缓存区的内容到客户端) M3 D3 y: d6 n5 q
<?php
//开启ob缓存
ob_start();
// 防止其他地方有缓存写入,我们先将缓存区清空
//输出缓冲区内容并关闭缓冲区
ob_end_flush();
//输出缓冲区中的内容
ob_flush();
$i = 1;
while(true){
echo $i;
//输出缓冲区中的内容
ob_flush();
//刷新系统输出缓冲区
flush();
//暂停1秒
sleep(1);
} 最近非常火爆的ChatGPT,有很多国内的客户端就利用了反向ajax原理实现了动态回复的效果。同样是HTTP请求,却可以实现不一样的效果。" s) K& C2 [2 W2 V8 t: Z' |
如果没有实现效果可以关闭PHP配置文件中的output_buffering = off3 O- }' p9 J+ u# W" w
注意:看网上说这个必须通过php配置文件关闭,不能通过ini_set()设置- J/ q# ^5 l' d0 r0 b2 @; M- F0 z" B
大家可以通过 php --ini 查看配置文件路径 关闭nginx的gzip压缩功能、代理缓存及开启keep长连接
" x0 y. M* h0 Z e. k$ nlocation ~ [^/]\.php(/|$) {
proxy_buffering off; #关闭代理缓存
gzip off; #注意这个是关闭gzip压缩功能,必须要
fastcgi_keep_conn on; #开启keep连接,这个必须要
fastcgi_pass unix:/dev/shm/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
} 前端对接
7 ^- x0 u, `; B" U6 j) o( }/ [前端对接有点麻烦,如果你使用jquery可能无法实现实时显示的效果。因为jquery的Ajax请求有缓存作用,success的回调是请求完成后的回调,但是反Ajax是分段返回,返回第一部分数据后依然保持连接继续等待返回,不过我们可以使用原生js实现,具体如下:. |6 H8 O# K+ M5 x: ?
//创建请求对象
var xhr = new XMLHttpRequest();
//设置请求方法及url
xhr.open('get','ajax.php',true);
//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//监听返回的数据
xhr.onreadystatechange = function (res){
console.log(res,this.responseText);
//可以在这里获取document节点实时显示数据
}
//发送请求
xhr.send();
|