十 24
1. Hidden iframe
将iframe的src指向一个url,server收到请求后,Keep-Alive。
数据直接以script的方式下发到Browser,Browser收到数据后直接执行。
只要不超时,链接会一直保留。
优:感觉这是真正的长连接,对stream也有完整的支持。
劣:Browser状态栏会一直处于“连接中”,ESC会导致链接断开,会有跨域问题
2. Script Tag
用JS创建一个script对象,将该对象的src指向一个url,Keep-Alive。
在一定时间内(超时前),如果sever有数据下发,则用script的方式发送到Browser。
Browser收到数据后直接执行,此时需要重建script对象,建立另一个链接。
优:没有Hidden iframe的缺点,也比较轻量
劣:不是真正的长链接,每收到一个新的下发数据,都需要重新建立链接
3 AJAX
用JS创建一个XHR对象,将该对象的src指向一个url,Keep-Alive。
在一定时间内(超时前),如果sever有数据下发,则通过已建立的链接发送到Browser。
Browser收到数据后直接执行,此时需要重建XHR对象,建立另一个链接。
优:没有Hidden iframe的缺点
劣:存在跨域问题,不是真正的长链接,每收到一个新的下发数据,都需要重新建立链接
2 和 3也可以叫做Long Polling
除了这三种方法,还可以用Flash,由Flash和Server通信,页面用过JS和Flash通信。
这可以实现真正的下发,甚至不需要维护长链接。
但也可能存在被防火墙屏蔽的问题。
三种方法都用php模拟了一下:
Hidden Iframe
<html>
<head>
<script>
function callback(data)
{
document.getElementById("t").value = data + "\n" + document.getElementById("t").value;
}
callback("abc");
</script>
</head>
<body>
hello
<textarea id="t"></textarea>
<iframe src="/hiddeniframe.php" width="0" height="0"></iframe>
</body>
</html>
<?php
ob_end_flush();
echo "<script>";
echo "domain=serverpush";
echo "</script>";
for( ; ; )
{
$t = time();
echo "<script>";
echo "parent.callback($t);";
echo "</script>";
flush();
sleep(1);
}
?>
Script Tag
<html>
<head>
<script>
function callback(data)
{
document.getElementById("t").value = data + "\n" + document.getElementById("t").value;
}
function connect()
{
var _script = document.createElement("script");
_script.setAttribute("type", "text/javascript");
_script.setAttribute("src", "script.php");
document.getElementsByTagName("head")[0].appendChild(_script);
}
connect();
</script>
</head>
<body>
<textarea id="t"></textarea>
</body>
</html>
<?php
sleep(10);
$r = time();
echo "callback($r);";
echo "setTimeout(connect, 1000)";
?>
AJAX
<html>
<head>
<script>
function callback(data)
{
document.getElementById("t").value = data + "\n" + document.getElementById("t").value;
}
function connect()
{
var ajax = new XMLHttpRequest;
ajax.open("POST", "ajax.php");
ajax.onreadystatechange = function()
{
if (ajax.readyState == 4)
{
if (ajax.status == 200)
{
callback(ajax.responseText);
setTimeout(connect, 1000);
}
}
}
ajax.send();
}
connect();
</script>
</head>
<body>
<textarea id="t"></textarea>
</body>
</html>
<?php
sleep(10);
echo time();
?>
Tagged with: AJAX • Server Push • Web • 服务器推
一 23
想在mail的一个页面里,用隐藏iframe引用soso的一个页面,加载后将数据取出。
但一直报错,说…undefine。
到群里咨询过前台高手们,原来又遇到所谓的“跨域”问题了。
处于安全性的考虑,JavaScript不允许脚本处理来自不同域(Domain)的资源。
用里的话说,就是同源策略(Same-Origin Policy):
一个脚本只能读取与它同源(如由同一个主机下载、通过同一个端口下载或者下载协议相同)的窗口或文档的属性。
对于我的需求,常规的解决跨域问题的方法都不适用,而非常规手段又过于复杂,代价太大。
只有作罢了。
我所知的常规手段包括:
- 设置document.domain,只适合位于不同子域的页面中使用
- 采用proxy页面中转
非常规手段
- 借助Flash
- GreaseMonkey
很久没写JS了~~~
function Search()
{
var keyword = $("keyword").value;
debug("search for " + keyword);
var url = "http://qzone.soso.com/qz.q?&sc=qz&pid=qz.s.idx&ch=s.qz.diary&pg=1&ty=diary&w=" + keyword;
var soso = document.createElement("iframe");
soso.setAttribute("onload", "ParseResult()");
soso.setAttribute("src", url);
soso.setAttribute("id", "soso");
document.getElementsByTagName("body")[0].appendChild(soso);
return false;
}
function ParseResult()
{
debug("begin to parse");
var soso = $("soso");
if(!soso)
return;
// var ids = document.frames[0].contentWindow.document.getElementsByTagName("div");
var ids = document.getElementById("soso").contentWindow.document.getElementsByTagName("div");
for( var i = 0; i < ids.length; i++)
{
var d = ids[i];
if( d.getAttribte("ss_c") == "qz.show.res")
{
debug("found");
}
else
{
debug(d.className);
}
}
debug("end of parse");
document.getElementsByTagName("body")[0].removeChild($("soso"));
}
Tagged with: JavaScript • 跨域
一 17
Google Reader有462个GM脚本(GreaseFire的结果),而整个qq.com的域名只有一个,是用来优化qq.com的打印功能的。
这样的对比反映出了Geek们对两个域名的认同差异吧。
早上起床,写了一个用于用于阅读空间GS脚本。
just for fun啦,主要功能是在阅读时改变背景色,因为感觉现在的色彩有点单调。
已经上传到userscrips,可以在这里找到。
效果图:)

可惜Qzone对Firefox的支持还不好,否则也可以做一个:)
出去晒太阳了~~~
Tagged with: greasemonkey • qqmail • reader
一 16
如果用obj.onclick = function(){…},
则脚本会异常终止。
改用addEventListener(“click”, function(){…}, true),
则一切正常。
Tagged with: greasemonkey • JavaScript
十 22
想给自己写的log加上一个WYSIWYG,
于是google一番,
找到某人推荐的fckedit。
其实之前已经在wp里试过,感觉一般。
不过这次是要和自己的程序整合,所以了解比之前深入。
看了一下sample,然后用了不到10分钟就拼凑出一个可以工作的版本。
得益于实用的例子、详细的注释和通用的命名,
优秀的程序都应该这样。
Tagged with: editor WYSIWYG php
七 07
function objectClone(obj,preventName){
if((typeof obj)==’object’){
var res=(!obj.sort)?{}:[];
for(var i in obj){
if(i!=preventName)
res[i]=objectClone(obj[i],preventName);
}
return res;
}else if((typeof obj)==’function’){
return (new obj()).constructor;
}
return obj;
}
同事的作品:)
五 12
var wintype = !!os[1];
取变量的Boolean值,
应该相当于 var wintype = os[1]?true:false,
但显然简洁很多。
十二 21
function getHeight(){
s = “网页可见区域宽:”+ document.body.clientWidth;
s += “\r\n网页可见区域高:”+ document.body.clientHeight;
s += “\r\n网页可见区域高:”+ document.body.offsetWeight +” (包括边线的宽)”;
s += “\r\n网页可见区域高:”+ document.body.offsetHeight +” (包括边线的宽)”;
s += “\r\n网页正文全文宽:”+ document.body.scrollWidth;
s += “\r\n网页正文全文高:”+ document.body.scrollHeight;
s += “\r\n网页被卷去的高:”+ document.body.scrollTop;
s += “\r\n网页被卷去的左:”+ document.body.scrollLeft;
s += “\r\n网页正文部分上:”+ window.screenTop;
s += “\r\n网页正文部分左:”+ window.screenLeft;
s += “\r\n屏幕分辨率的高:”+ window.screen.height;
s += “\r\n屏幕分辨率的宽:”+ window.screen.width;
s += “\r\n屏幕可用工作区高度:”+ window.screen.availHeight;
s += “\r\n屏幕可用工作区宽度:”+ window.screen.availWidth;
s = “\r\n网页正文全文高:”+ document.body.scrollHeight;
alert(s);
}
最近评论