十 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 • 服务器推
十 12
花了半天时间,看了一次http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
下面是相关的笔记和理解,
感觉很多Status Code在实际的BS通信中都不常见,
更多像是为了定义完备的协议语义,
而这些语义现在已经部分由更上层的协议或者应用实现。
1xx Informational
100 Continue
如果server可能拒绝request,则client只发送header部分,试探server的反应
如果server接受,则返回100,于是client再发送剩余的body部分
101 Switch Protocol
2xx Successful
200 OK
201 Created
有资源因Request而产生
202 Accepted
Request要求的动作已经被记录,但真正的动作要等待若干时间才执行,而且不保证一定执行
203 Non-Authoritative Information
204 No Content
google.cn的web server会返回
205 Reset Content
206 Partial Content
用于断点续传,起始位置由Range指定。(可以参考迅雷的输出)
3xx Redirection
User Agent需要处理循环的问题
300 Multiple Choices
目标已变,有若干个替代品可供选择
301 Moved Permanently
目标URI在Location里定义,除了HEAD和GET请求外,不能自动重定向
对SEO不会有负面作用
302 Found
临时重定向,是否用Moved Temporarily这个名字比较合适?
目标URI在Location里定义,除了HEAD和GET请求外,不能自动重定向
对SEO有负面作用
303 See Other
和302类似,但期待User Agent用GET来请求Location里指定的URI
304 Not Modified
通常Request会带If-Modified-Since
不能带message-body
305 Use Proxy
期待User Agent会使用Location中指定的Proxy地址,来访问数据
只能由origin server产生
306 (not used)
之前的版本用过,已经废弃,作为保留字
307 Temporary Redirect
没看出和302有什么不同
只有HTTP/1.1支持
4xx Client Error
在message-body中,可以自定义给User的提示
400 Bad Request
server不能理解Request的格式
用telnet可以很容易模拟
401 Unauthorized
不能通过HTTP Authentication
response header必须包含WWW-Authoricate,request header可能包含Authorization
402 Payment Required
保留字
403 Forbidden
如果不希望暴露过多的信息,可以用404代替
404 Not Found
最常见的4字头Status Code,通常会自定义
405 Method Not Allowed
response header需要包含Allow,列出支持的method
406 Not Acceptable
response不被request header中的Accept做支持
除了HEAD,response会给出包含更多信息的entity
entity format由request header中的Content-Type决定
407 Proxy Authentication Required
与401类似
Proxy的response header必须包含Proxy-Authenticate
408 Request Timeout
409 Conflict
需要User干预解决
在PUT的时候可能遇到
410 Gone
URI已经不存在,且不提供3xx来重定向
如果server没有足够的信息来判断URI的不存在是temporary还是permanent,可以用404代替
411 Length Required
request header中缺少Content-Length
412 Precondition Failed
413 Request Entity Too Large
如果只是temporary,可以包含Retry-After,指定重试的时间间隔
414 Request-URI Too Long
有几种可能导致这个返回码的情况
将POST当成了GET
循环重定向,每次都append上当前URI
攻击
415 Unsupported Media Type
416 Requested Range Not Satisfiable
参考206
417 Expectation Failed
不能满足request header中的Expect,参考100
5xx Server Error
500 Internal Server Error
在server没有输出正确的response header的时候会出现
501 Not Implemented
502 Bad Gateway
由gateway或者proxy返回,表明上游server不能返回请求的URI
503 Service Unavailable
server可能过载,或者正在维护
可以返回Retry-After,如果没有,则视作500
504 Gateway Timeout
上游server不能及时返回
505 HTTP Version Not Supported
Tagged with: http • rfc
十二 15
用没有语法高亮、只有黑白的notepad来看html代码是比较痛苦的,
还好默认的查看程序可以修改。
打开注册表项“HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Internet Explorer\View Source Editor\Editor Name”,
修改的“默认”字符串,在数值数据栏中写入其他编辑器的执行文件位置。
如果注册表里没有这个表项,可以自己创建。
修改之后不需要重启,马上生效。
Tagged with: Editor • IE
十 16
下面是一个比较典型的IE发出的HTTP请求,其中UA部分含有Mozilla。
GET / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, */*
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; CIBA; .NET CLR 2.0.50727; InfoPath.1)
Host: g.cn
Connection: Keep-Alive
But why,微软为什么会对Firefox这么好?我一直都很好奇。
Google发现世界上有其他人也有同样的疑问,而且找到了wikipedia上的解释。
简单说明一下,因为这里的Mozilla不是现在的mozilla.org,而是当年Netscape Navigator的codename。
而IE这样做,是为了表示和Navigator的兼容,毕竟但是Navigator才是主流。
只是不知道为什么,这样的做法会延续了下来,造成了今天的疑问。
最近评论