HTML5 服务器发送事件(server-sent event)允许网页获得来自服务器的更新。通过官网的介绍可以看出是接收服务器发送数据,千万不能和ajax混淆,网上大片博文的介绍对其解读是错误的,导致让我差点觉得这个事件很鸡肋。
先看通用案例:
html5:
<script type="text/javascript"> if(typeof(EventSource)!=="undefined") { //浏览器支持 var api = 'server.php'; var source=new EventSource(api); source.onmessage=function(event) { console.log(event.data) }; } else { //浏览器不支持 } </script>
php:
<?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $time = date('Y-m-d H:i'); echo "data: The server time is: {$time}\n\n"; flush();
上面是根据w3c的代码修改的,通过谷歌调试发现每隔3秒还是会请求1次,天呐,w3c官网是不是搞错了.如果是这样的话我还不如选择ajax,写起来不是更爽?于是继续找,发现网上一堆重复的请求博文很头疼,最后终于在mozilla发现原来可以阻塞,于是有了下面的高效案例。
再看高效案例:
php:
<?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); while (1) { $time = date('Y-m-d H:i:s'); echo "data: The server time is: {$time}\n\n"; ob_flush(); flush(); sleep(1); }
以上代码通过阻塞可以达到约30s请求一次,数据是每隔1秒发送1次,但是考虑一般用户在页面停留时长肯定能达到30s的,于是有了下面的代码
php:
<?php ini_set('max_execution_time', '0'); header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); while (1) { $time = date('Y-m-d H:i:s'); echo "data: The server time is: {$time}\n\n"; ob_flush(); flush(); sleep(1); }
以上代码通过限制脚本执行时间,可以达到7分钟请求脚本1次,7分钟自动请求1次,并且这7分钟都是每秒推送,已经非常高效
超时问题延伸:
通常情况下,php设置不超时,但是web服务器本身是不可能等待php那么久的,会直接抛出超时,但是实际上php脚本还是在默默无闻的跑着。
但是为什么上面的脚本不会直接抛出超时,个人猜测或许是apache和nginx对于Content-Type: text/event-stream类型的都不会直接超时。另外再想想文件流的传输过程貌似web服务器也不会说传输中断的问题。
window.setInterval(method,time)方法本身会返回一个资源句柄,使用clearInterval(Intervalid)方法即可清除定时器<script> var num=0; //每隔1秒再控制台输...
<form action="save.php" method="post" target="nm_iframe"> &nbs...
<!doctype html> <html> <head> <meta charset="utf-8"> <title>无标题文档</title> <script type...
通过FormData对象可以组装一组用 XMLHttpRequest发送请求的键/值对。它可以更灵活方便的发送表单数据,因为可以独立于表单使用。如果你把表单的编码类型设置为multipart/form-data ,则通过FormData传输的数据格式和表单通过submit() 方法传输的数据格式相同...
维护老项目中客户提到一个页面中有6个表单以上,导致每次保存一个其他的数据全部丢失,自己比较懒没有全部更换为ajax.用户每次输入完成或者选择完成记录cookie,每次提交后加载页面完成初始化cookie即可。以下代码取自w3school比较完善,之前在其他博客使用的经常出现bug,这个比较推荐使用:...
//我们创建每个函数默认都有一个prototype(原型)属性,这个属性是一个对象 //1.我是普通的构造方法,我的属性叫实例属性,我的方法叫实例方法 /* function Box(name,age){ this.name=name; this.age=age; this.run...