blogjava-凯发k8网页登录

blogjava-凯发k8网页登录http://www.blogjava.net/emu/zh-cnsat, 08 apr 2023 20:41:03 gmtsat, 08 apr 2023 20:41:03 gmt60极简的switch控件http://www.blogjava.net/emu/archive/2019/10/02/434717.htmlemuemutue, 01 oct 2019 22:45:00 gmthttp://www.blogjava.net/emu/archive/2019/10/02/434717.htmlhttp://www.blogjava.net/emu/comments/434717.htmlhttp://www.blogjava.net/emu/archive/2019/10/02/434717.html#feedback0http://www.blogjava.net/emu/comments/commentrss/434717.htmlhttp://www.blogjava.net/emu/services/trackbacks/434717.html需要在html页面上用到一个switch控件,html5没有现成的,网上流传的版本都有点复杂,代码量偏大甚至有独立的css和js片段的依赖,用起来不像html控件那么简单,有一些动画之类的需求镀金也不是太必要,随手写个极简版的用着:
<pre onclick="this.c=!this.c;style.backgroundcolor=c?'green':'';innerhtml=c?'on   ○':'○  off'"
style
="border-radius:0.7em;border:1px solid black;padding:0 0.4em;display:inline;float:right">○  offpre>

用pre控件一是为了让字体等宽避免宽度的微小变化,二是可以方便的填空格进去调整宽度而不用填 

打开关闭状态可以通过读取元素的c属性,当然也可以直接用标记相应属性的全局变量来代替,免去了再读取元素属性的麻烦:

<script>
var switchstate;    
script>
<pre onclick="style.backgroundcolor=(switchstate=!switchstate)?'green':'';innerhtml=switchstate?'on   ○':'○  off'"
style
="border-radius:0.7em;border:1px solid black;padding:0 0.4em;display:inline;">○  offpre>


emu 2019-10-02 06:45
]]>
整理了最近百年的藏历数据,做了个公历藏历映射的小工具http://www.blogjava.net/emu/archive/2019/01/30/433627.htmlemuemuwed, 30 jan 2019 05:34:00 gmthttp://www.blogjava.net/emu/archive/2019/01/30/433627.htmlhttp://www.blogjava.net/emu/comments/433627.htmlhttp://www.blogjava.net/emu/archive/2019/01/30/433627.html#feedback0http://www.blogjava.net/emu/comments/commentrss/433627.htmlhttp://www.blogjava.net/emu/services/trackbacks/433627.html一个gihub项目里面,今年临近藏历新年,却发现以往的很多藏历网站都没有更新明年的数据了,正好弄到了最近一百年的藏历数据,花了点时间全部都更新了进去,顺便申请了一个还不错的域名 zangli.pro, 发布了一个新网站,方便大家随时查询或者在自己的产品中直接引用藏历公历的换算脚本。

emu 2019-01-30 13:34
]]>
用webcrypto做aes原生加解密http://www.blogjava.net/emu/archive/2017/06/12/432595.htmlemuemumon, 12 jun 2017 09:48:00 gmthttp://www.blogjava.net/emu/archive/2017/06/12/432595.htmlhttp://www.blogjava.net/emu/comments/432595.htmlhttp://www.blogjava.net/emu/archive/2017/06/12/432595.html#feedback0http://www.blogjava.net/emu/comments/commentrss/432595.htmlhttp://www.blogjava.net/emu/services/trackbacks/432595.html一个妹子聊到在前端做aes加密,妹子说有一些开源的库,我想webcrypto提出来这么多年,应该了吧?写个加测试页面试试看:

doctype html>
<html>
    <head>
        <meta name="author" content="emu">
        <meta name="keywords" content="webcrypto aes-cbc aes-gcm">
    head>
    <body>
        <div id="out">div>
        <script type="text/javascript">
            
function output(sign) {
                document.getelementbyid(
"out").innerhtml  = sign  "
";
            }
            
function buffertohex(b){
                
var dataview = new dataview(b);
                result 
= "";
                
for (var i = 0; i < b.bytelength; i  = 4) {
                    tmp 
= dataview.getuint32(i).tostring(16);
                    result 
= (tmp.length == 8 ? "" : "0" tmp;
                }
                
return result;
            }

            
function buffertostring(b){
                
//new textdecoder().decode(b)
                var hex=buffertohex(b);
                
var result=unescape(hex.replace(/(..)/g,"%$1"));
                
return result;
            }
            
function stringtobuffer(s){
                
//new textencoder().encode(s);
                 var a = s.split("");
                 
for (var i = 0; i < a.length; i) {
                        a[i] 
= a[i].charcodeat(0)
                 };
                 
var result = new uint8array(a);
                 
return result;
            }


        
var texttobeencrypted = 'hello world!';
        
var buffertobeencrypted=stringtobuffer(texttobeencrypted);
        
var buffertobedecrypted;
        
var pwd="let me try this password"
        
var password = stringtobuffer(pwd);
        
var salg="aes-cbc";//aes-gcm部分浏览器不支持
        var c = window.crypto || window.mscrypto;
        
var subtle = c.subtle || c.webkitsubtle;
        
var iv = c.getrandomvalues(new uint8array(16));
        
var alg = { name: salg, iv: iv };
        
var op=c.subtle.digest('sha-256', password)
        
var encryptkey,decryptkey,hash;
        
if(("then" in op)){
            op.then(
function(buffer){
                hash
=buffer;
                c.subtle.importkey('raw', hash, alg, 
false, ['encrypt']).then(function(buffer){
                    encryptkey
=buffer;
                    c.subtle.importkey('raw', hash, alg, 
false, ['decrypt']).then(function(buffer){
                    decryptkey
=buffer;
                    doencrypt(alg,encryptkey);
                    })
                })
            });
        }
else{
            op.oncomplete
=function(e){
                
var hash=e.target.result;
                
var op=c.subtle.importkey('raw', hash, alg, false, ['encrypt']);
                op.oncomplete
=function(e){
                    encryptkey
=e.target.result;
                    op
=c.subtle.importkey('raw', hash, alg, false, ['decrypt']);
                    op.oncomplete
=function(e){
                        decryptkey
=e.target.result;
                        encryptwithcryptooperation(alg,encryptkey);
                    }
                }
            }
        }
        
function doencrypt(alg,encryptkey){
            
var op = c.subtle.encrypt(alg, encryptkey, buffertobeencrypted);
            op.then(
function(buffer){
                    buffertobedecrypted
=buffer;
                    output(
"pwd: "pwd" alg:
"salg" 
encrypt(
"texttobeencrypted  ")=" buffertohex(buffer));
                    dodecrypt(alg,decryptkey);
                })
        }

        
function dodecrypt(alg,decryptkey){
            
var op = c.subtle.decrypt(alg, decryptkey, buffertobedecrypted);
            op.then(
function(buffer){
                output(
"pwd:"pwd"  alg:
"salg" 
decrypt("buffertohex(buffertobedecrypted)  ")=" buffertostring(buffer));
            })
        }

        
function encryptwithcryptooperation(alg,encryptkey){
            
var op = c.subtle.encrypt(alg, encryptkey);
            op.onerror
=function(e){output(salg"  unsupported")}
            op.process(buffertobeencrypted);
            op.oncomplete
=function(e){
                buffertobedecrypted
=e.target.result
                    output(
"pwd: "pwd" alg:"salg" 
encrypt("texttobeencrypted  ")=" buffertohex(buffertobedecrypted));
                
//decryptwithcryptooperation(alg,decryptkey)
                settimeout(decryptwithcryptooperation,0,alg,decryptkey)
            }
            op.finish();
        }        
        
function decryptwithcryptooperation  (alg,decryptkey){
            
var op = c.subtle.decrypt(alg, decryptkey);
            op.onerror
=function(e){(salg"  unsupported")}
            op.process(buffertobedecrypted);
            op.oncomplete
=function(e){
                
if(!e.target.result){
                    output(
"ie is crazy!
");
                    encryptwithcryptooperation(alg,encryptkey)
                }
else
                    output(
"pwd:"pwd"  alg:"salg" 
decrypt("buffertohex(buffertobedecrypted)  ")=" buffertostring(e.target.result));
            }
            op.finish();
        }
        
script>
    body>
html>

测试下来感觉各个浏览器支持程度还是参差不齐,ie11和edge都是不同的实现方式,ie11甚至还会随机出现oncomplete的时候result数据都还没有ready的情况,甚至于有的时候完全相同的入参(包括随机数也相同)加密出来的结果居然会不同,也就是说有的时候加密算法自己会加密错,出来的结果根本就无法被正确解密,实在是个半成品:


(第一次加密错了,第二次加密对了解密错了,第三次终于加解密都对了)


(第一次加密错了,第二次对了)


emu 2017-06-12 17:48
]]>
用优图继续优化论坛http://www.blogjava.net/emu/archive/2016/02/27/429464.htmlemuemusat, 27 feb 2016 12:21:00 gmthttp://www.blogjava.net/emu/archive/2016/02/27/429464.htmlhttp://www.blogjava.net/emu/comments/429464.htmlhttp://www.blogjava.net/emu/archive/2016/02/27/429464.html#feedback0http://www.blogjava.net/emu/comments/commentrss/429464.htmlhttp://www.blogjava.net/emu/services/trackbacks/429464.html

加好后,流量唰唰唰的就掉下来了:







每天流量从20g~30g下降到1g以下,相应的优图流量也上到接近2g。



哎呀,前面买了个大流量包这下怎么用的完啊?




emu 2016-02-27 20:21
]]>
用腾讯云优化一个公益论坛http://www.blogjava.net/emu/archive/2016/02/19/429374.htmlemuemufri, 19 feb 2016 09:56:00 gmthttp://www.blogjava.net/emu/archive/2016/02/19/429374.htmlhttp://www.blogjava.net/emu/comments/429374.htmlhttp://www.blogjava.net/emu/archive/2016/02/19/429374.html#feedback0http://www.blogjava.net/emu/comments/commentrss/429374.htmlhttp://www.blogjava.net/emu/services/trackbacks/429374.html〇、背景

       几年前由于发起寻亲项目的关系,和b网站开展了合作。b网站是国内最大的寻亲网站,几年来通过该网站和家人团聚的案例已经达到1397例。b论坛是网站中最活跃的板块。当时论坛遇到一些不稳定的情况,因为b论坛是用discuz!搭建的,而discuz!当时刚好被腾讯收购,要获得专业支持相对容易,我们开始把b论坛迁移到腾讯云上面,由discuz!的志愿者协助维护直到去年底离职,把论坛的管理权限交给我。

一、论坛出问题了

      我不对于php和linux都不熟,交接后看到论坛工作还算正常,也很长一段时间没有去关注,直到前几天,网站管理员突然发来了这个:




这是什么鬼?臣妾不懂啊……只好硬着头皮登上服务器去看看。



还好,大概可以猜到出什么事了:数据盘不够用了。那应该很好解决吧?扩数据盘?

二、cos

用腾讯云服务器而不是自己买服务器的一个好处就是,很多资源可以按需用,按需扩,包括硬盘。不过有个限制就是,买服务器的时候系统盘和数据盘都必须要买“云硬盘”而不能用本地盘。买云硬盘还有个附加的好处是可以申请开通硬盘快照功能,迁移复制服务器唰唰的。

但是云硬盘的性能跟本地硬盘是有差距的,处于性能考虑,志愿者选择了性能更好的本地硬盘,这样就导致硬盘满了以后没有办法扩了。几年来,寻亲的网友们每天上传大量的高清图片线索,终于在世纪寒流这几天把硬盘挤爆了。



不过扩硬盘本来也不是最佳选择,比扩硬盘更好的选择是:不用硬盘!

腾讯云为这种ugc文件提供的凯发天生赢家一触即发官网的解决方案是
 ,当前版本是cos3.0。cos 大概的意思就是,你有一大堆文件(比如网站用户上传的照片),只知道量很大,不知道有多少,不但需要找个地方存着,还随时有可能需要在某个网页上引用它。那么平台提供一个服务器让你把文件放上去,并提供web访问和api上传和管理接口,你就不用把文件传到自己服务器了。

个人认为使用cos的好处是:
1 能够提供几乎无限量的文件存储空间,按存储量和访问量收费
2 很大的免费额度:50g的免费空间,每计费周期内10g的回源流量,每计费周期内100万次的免费访问次数(实际上cos通常在cdn后面提供服务,因此实际上每个计费周期可以提供10g和100万次回源服务,配合恰当的cdn缓存策略,已经可以满足很大的访问量)。
因此用cos不但从此不用纠结容量爆仓的问题,也不用为没有使用到的容量预先买单花冤枉钱,而且还不用自己的服务器的硬盘和网卡来扛这些流量,服务器的带宽和硬盘i/o压力也立刻就下来了。

cos的使用也很简单:
1 建个仓库(bucket),以后附件就往这个仓库里面传了。


2 修改上传附件页面,使用腾讯云提供的api把文件上传到cos……开玩笑了,作为懒人,当然是提工单申请开通cos的ftp权限啦



大概两个钟头后收到消息说ftp开通了。

3 用论坛创始人身份登录discuz,打开远程附件


远程访问url可以域名解析到cos源上,不过这样附件都要走idc流量,不但贵,也没有实现静态文件就近访问的目标,因此实际使用的时候最好在cos服务的上面加一层cdn:
 



现在用户新上传的附件都自动到cos里面了。然后我们来对付旧的附件吧。这时我们要用到回源功能了。先准备好一个回源专用的域名,修改httpd.conf(apache)或者conf.d(nginx)添加一个新的server,documentroot(或者root)指向服务器上discuz的附件目录 data/attachment 并修改域名解析,浏览器里面访问一下确认回源域名可以访问到附件。然后修改cos的回源配置:




这样如果有人访问cos的时候cos上没有相应的文件,服务器就会到老的服务器上获取文件并缓存下来。通过浏览器访问附件确认回源成功后,登录数据库 
update cdb_attachments set remote = '1' 把所有的附件都更新为远程的。这样数据就会随着用户的访问慢慢迁移到cos上了,这个过程平滑无感知,不过就是不知道迁移到什么时候成功。

可是我想释放硬盘空间出来啊怎么办?先装上ftp神器 lftp再说。不得不说,在linux下,lftp实在是个神器。打开lftp,open登上cos的ftp服务器,mirror -rl ..... 老附件通通迁移上cos咯。

偷懒用ftp而不是修改上传页面代码的一个代价是,有的时候ftp失败,会有一些附件仍然被扔在cvm硬盘上。可以定期
update cdb_attachments set remote = '1' 把附件都改成远程的,让cos回源到cvm上。不过就算这样,冷门的附件仍然可能长时间没有办法同步到cos上。crontab一个lftp任务定期把附件同步上cos可以解决问题。不过如果懂一点点开发的话,写一点点脚本用inotify自动同步一下显得会看起来好点儿:







三、 cdn优化:动静分离

      内容分发网络(content delivery network)大概的意思就是,我大腾讯在全国成百上千个机房里面屯有无数的服务器,如果某个边远地区的用户要访问你放在上海的一份数据,山长水远的跑到上海机房来拉数据肯定快不了,如果我把这份数据先放在这个边远地区里,离用户最近的一个机房呢?那速度就不一样了。而且这个边远地区的机房流量还比我大上海三通机房的流量便宜了一大截。不过有个前提是服务器要提前知道用户将要访问的数据,并提前拉取这份数据缓存在当地,因此一般只用来服务静态的图片、样式表、脚本、超文本、flash这些资源。



      b论坛其实去年就用上了cdn,不过用的是一个比较冷门的用法:动态加速。这个用法就是说,先假设我网站的所有请求都是静态的,这样用户所有的请求都访问在当地的服务器(边缘服务器),然后边缘服务器检查一下这个请求的资源我有没有缓存啊,没有的话边缘服务器再受累跑去你的服务器上拉这个数据,把数据返回给你,并且尝试缓存这个数据以备下次使用。然后对于不允许缓存的动态请求,只要声明一个策略,比如“php文件缓存时间0秒”这样,让边缘服务器直接访问源cvm服务器就好了。

    这样做的好处是配置简单,不需要关心动静分离,并且不但静态的文件都可以被边缘服务器缓存,动态的请求也可以获得cdn网络的传输加速 。坏处就是“流量double”。也就是说,你不但要给cvm购买外网带宽,cvm的动态数据送到边缘服务器以后,你还要再购买一次从边缘服务器到用户那里的cdn带宽(或者流量)。

    另外一个附加的“缺点”是,cdn网络总是尽可能快的从cvm服务器拉取全部数据,再按照访客用户网络的速度再把数据吐出去。这其实是最佳策略,因为cvm的带宽已经买单了,不跑慢也是浪费,但是带来的问题就是cvm监控上看起来,再多的带宽都会被跑满,好像带宽永远都不够用。因此前任的管理员购买了非常多的带宽来试图满足永远喂不饱的cdn网络,带宽成了b论坛最沉重的成本。
    

 
(15m的带宽,经常性的被cdn跑满) 


    贸然的减少带宽也是不合适的,最好的做法还是做尽量彻底的动静分离,静态的部分还是用cos托管源和ftp托管源来喂饱cdn网络,让用户尽可能体验好;动态的部分直接访问cvm,根据用户日常实际产生的带宽情况再加上足够充分的冗余来采购就可以。

    传统的动静分离手段是最好的:直接修改html、css和js,通过静态专用域名访问静态资源。但是这样做需要很多的开发工作量,作为懒人,我直接用上了大杀器:rewrite!




    懒得给每个域名打马赛克了,也不是什么机密。这几条规则是这样:
1 对于普遍图片超大的png图片,自动转向到优图系统进行jpg压缩。因为监控发现少数png图片占了很大的流量比重。
2 对于用户上传到附件,自动转向到attachment子目录(cos源),这样cvm就不需要承担附件文件的存储了(零星缺失的文件cos回源启用了回源专用的域名)
3 对于系统的静态文件,自动转向到static子目录(ftp源),不统一使用cos源的原因是,cdn回源到ftp源是免费的,但是ftp源只有6g的存储空间。回源到cos空间几乎是无限的,但是是有可能收费的。
这样就把cvm上出了favicon.ico之外的几乎所有静态文件都分离出去了。要注意的是如果盗链严重的话,原本nginx上的防盗链规则也要相应的设置到cdn上去。




动静分离后cdn的整体命中率从瓶颈50%以下一下提升到75%以上,对于cvm的压力大大减小了。看一下分域名的命中率数据




在不对论坛程序做细致的优化的情况下,只是通过策略调整达到这样的命中率,还算比较理想了。

不过这样做了以后,cdn的流量费用并没有下降啊。因为b论坛的cdn采用了峰值带宽计费模式,因此观察了一下cdn监控的带宽数据,发现了一个很有意思的问题:



cdn的峰值带宽按天波动非常大。细看到具体的带宽比较大的一天更明显:



这天是央视《感动中国2016》b论坛的两个发起人入选带来的一个访问波峰。

像这样的带宽曲线模式,按照带宽购买cdn是非常浪费的。果断切换到流量包计费模式,cdn费用从每月>¥500(每年大约¥6000~¥8000)下降到每年<6t(每年大约2000以内)

动静分离后cvm的实际动态带宽需求有多少呢?后面上了负载均衡之后没有地方可以截屏几台服务器完整的带宽总和曲线了,总体是2m带宽平常跑不满,但是偶发集中的访问会超,所以两台cvm做负载均衡,各开了2m的带宽,保证平常有超过一倍的带宽冗余。


四:memcache和云数据库

b论坛迁移到腾讯云的时候就使用了云数据库,数据量虽然不大,但是数据库访问量不小,购买的是能支撑2400qps的50g/2000mb型号。


 (7天后到期,不需要续了) 

但是查看了一下discuz的优化选项,发现内存缓存优化项都没有打开。在cvm里装上一个memcached测试了一下,数据库请求可以有效的降低到100qps以下。这样高配云数据库就太浪费了,换个10g/360mb/120qps的就足够了。不过性能冗余够不够?discuz支持master/slave的,先提个工单申请一个免费的slave。



配置slave后观察了几天,即使在峰值查询接近700qps的情况下数据库也没有出现访问瓶颈,腾讯云数据库的性能还是相当厚道的,这个性能冗余是足够的。




(某海量网站配置错误导致出现大量404页面,顺带给论坛带来了很大压力)

这样数据库费用从¥2240/年陡降到¥210/年了。已经省了这么多钱,再买个c型的memcached好了,每天2元,每年大概700元。
cvm本机运行一个memcached虽然性能不错,但是始终要和其他本机服务竞争各种资源,而且考虑到后面要做负载均衡,也希望把登录态(session)丢到云里面去。


(memcache很轻松的扛住了情人节的感动中国带来的访问量)


修改了一下discuz的配置文件指向memcached,再修改php.ini把session也指向了memcached,这下cvm就没有“状态”了,可以很容易的替换,或者集成多个做负载均衡。

五:cvm和负载均衡



b论坛在腾讯云上一共两台cvm,对外提供服务的是一台配置有点豪华的服务器:



这台每年费用是 ¥16450,当然主要的钱都花在买带宽去喂cdn了



另一台不对外服务,只是有一个大的硬盘做数据备份。


一年¥1550。

经过上面一系列优化以后,原本买的cvm性能就太过冗余了,文件都丢到cos上去了,大硬盘备份也没有必要了。已经迁移到cos的文件剔除后,整个系统只剩下了4g,全部回迁到系统盘上面,数据盘也不需要了:



因为数据库在云上,附件文件也在cos上,本地没有什么动态的数据,这样系统备份也简单的多了,定期对系统盘做一个“系统镜像”就成,除了有一个问题:做系统镜像要关机。

墨菲定律告诉我们,永远要防着机器宕机!前面该清理的清理干净了,是时候做双机热备了。先把备份机的论坛服务也启动起来,session也指向memcached,然后添加一个负载均衡:


访问低谷的时候把主服务器关掉,做镜像,备份机自动扛住了全部访问量。

有了镜像以后换机型就方便了。新购一台服务器




因为充分使用了云数据库、memcache、cdn、cos等paas服务,又做了动静分离,cpu现在已经清闲的很,1核的性能是足够的。内存使用率也很低,内存其实1g也足够,不过cpu不够了还可以负载均衡,内存不够了就只有干瞪眼,所以多加1g冗余。

购买的时候就可以直接指定安装镜像,支付每年¥1250的费用,10分钟后,有了一台全新的服务器,配置host验证成功,加入到负载均衡后端列表里面

把权重分几次从原来的高配服务器分配到新服务器上,运行指标都还好,就是负载有点儿高,访问速度可能不是最优,也许是mysql或者memcache要通过网络访问导致的?



反正要做双机热备的,再买一台一样的服务器,加入负载均衡后台分摊一半的访问量,观察了一下cpu利用率和负载都下来了,虽然偶尔有一些瞬间的毛刺,反问上已经感觉不到差别。



这样就有了两台一模一样的服务器,平常分摊访问压力,一台宕机的时候负载均衡会自动发现并把访问全部导向到正常工作的服务器。未来如果有更大的访问压力随时可以新购机器,安装上镜像后加入负载均衡后端。

正好原来购买的服务器和数据库这阵子都要过期了,就都不用续费了。

六、对公益捐赠负责 

看看优化后比原来节省了多少:

cvm: 原来16450 1550=18000 , 优化后1250*2=2500



cdn cos:原来:¥6000~¥8000,优化后约 ¥2000(cos回源流量暂时还没收费,附件迁到cos后也不足50g还不需要存储费用,不过未来有可能产生少量费用。)

mysql memcache :原来 ¥2240,优化后210 700=910

总体相比原来优化大约 ¥22000 /年。

  虽然腾讯云一直对于公益组织免费扶持云资源,但是我觉得云资源和公益捐赠善款一样,也要用负责的态度抠门的用好,才是对支持企业负责任的态度。

最后,感谢腾讯云对公益事业的慷慨支持。打完收工。








emu 2016-02-19 17:56
]]>
jq的getscript函数不支持chaset?override掉!http://www.blogjava.net/emu/archive/2014/11/19/420314.htmlemuemuwed, 19 nov 2014 11:40:00 gmthttp://www.blogjava.net/emu/archive/2014/11/19/420314.htmlhttp://www.blogjava.net/emu/comments/420314.htmlhttp://www.blogjava.net/emu/archive/2014/11/19/420314.html#feedback1http://www.blogjava.net/emu/comments/commentrss/420314.htmlhttp://www.blogjava.net/emu/services/trackbacks/420314.html
其实我从来不用jq或者其他框架的,这两天偶然在一个小项目里面发现jq的一个小bug:getscript函数没有透传charset信息,如果试图在页面上加载一个跨编码的脚本的时候会导致编码错误。写了一个补丁函数覆盖掉原来的:

$.getscript=function(url, callback , charset){
    $.ajax({
        url: url,
        datatype: "script",
        success:callback,
        scriptcharset:charset
    })
}    

这几年代码写得很少,轻喷。这里是 ,同时也到jq的github上提交了

doctype html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://cdn.jsdelivr.net/jquery/1.11.1/jquery.js">script>

<script language="javascript">

script>
head>
<body>
body>
html>


emu 2014-11-19 19:40
]]>
大家好像都比较少关心webcrypto,试试写个简单的sha1/sha256/sha384/sha512实现看看http://www.blogjava.net/emu/archive/2014/09/27/webcrypto.htmlemuemusat, 27 sep 2014 13:40:00 gmthttp://www.blogjava.net/emu/archive/2014/09/27/webcrypto.htmlhttp://www.blogjava.net/emu/comments/418336.htmlhttp://www.blogjava.net/emu/archive/2014/09/27/webcrypto.html#feedback1http://www.blogjava.net/emu/comments/commentrss/418336.htmlhttp://www.blogjava.net/emu/services/trackbacks/418336.htmldoctype html>
<html>
    <head>
        <meta name="author" content="emu">
        <meta name="keywords" content="webcrypto sha1 sha256 sha384 sha512">
    head>
    <body>
        <div id=sha>div>
        <script type="text/javascript">
            
function output(sign) {
                document.getelementbyid(
"sha").innerhtml  = sign  "
";
            }
            
function buffertohex(b){
                
var dataview = new dataview(b);
                result 
= "";
                
for (var i = 0; i < b.bytelength; i  = 4) {
                    tmp 
= dataview.getuint32(i).tostring(16);
                    result 
= (tmp.length == 8 ? "" : "0" tmp;
                }
                
return result;
            }
            
function digest(s, callback, algorithm, errcallback) {
                
try {
                    
if (!errcallback) {
                        errcallback 
= callback;
                    }
                    
var c = window.crypto || window.mscrypto;
                    
var subtle = c.subtle || c.webkitsubtle;
                    
if (!algorithm) algorithm = "sha-512";
                    
var a = s.split("");
                    
for (var i = 0; i < a.length; i) {
                        a[i] 
= a[i].charcodeat(0)
                    };
                    
var data = new uint8array(a);
                    
var op = subtle.digest({
                        name: algorithm
                    }, data);
        
                    
if("then" in op){
                        op.then(
                            
function(buffer) {
                                callback(buffertohex(buffer));
                            }, 
function(e) {
                                errcallback(e);
                            })
                    }
else{
                        op.oncomplete
=function(s){                    
                            callback(buffertohex(s.target.result));
                        }
                    }
                } 
catch (e) {
                    errcallback(e);
                }
            }
            digest(
"test"new function("output('sha-1(test) : ' arguments[0])"), "sha-1");
            digest(
"test"new function("output('sha-256(test) : ' arguments[0])"), "sha-256");
            digest(
"hello"new function("output('sha-384(hello) : ' arguments[0])"), "sha-384");
            digest(
"world"new function("output('sha-512(world) : ' arguments[0])"), "sha-512");
        
script>

    body>
html>
使用了浏览器原生接口,对旧浏览器没有什么兼容性可言了,尤其是ie,一时半会儿还用不上。

emu 2014-09-27 21:40
]]>
下周一国际盲人节,查了一下网上的盲文资料写了一个把中文转换成盲文的脚本玩玩。http://www.blogjava.net/emu/archive/2012/10/12/389481.htmlemuemufri, 12 oct 2012 09:41:00 gmthttp://www.blogjava.net/emu/archive/2012/10/12/389481.htmlhttp://www.blogjava.net/emu/comments/389481.htmlhttp://www.blogjava.net/emu/archive/2012/10/12/389481.html#feedback1http://www.blogjava.net/emu/comments/commentrss/389481.htmlhttp://www.blogjava.net/emu/services/trackbacks/389481.html阅读全文

emu 2012-10-12 17:41
]]>
偶然发现7年前受到的offer。7年,一晃而过http://www.blogjava.net/emu/archive/2012/08/27/386379.htmlemuemumon, 27 aug 2012 11:21:00 gmthttp://www.blogjava.net/emu/archive/2012/08/27/386379.htmlhttp://www.blogjava.net/emu/comments/386379.htmlhttp://www.blogjava.net/emu/archive/2012/08/27/386379.html#feedback1http://www.blogjava.net/emu/comments/commentrss/386379.htmlhttp://www.blogjava.net/emu/services/trackbacks/386379.html黄xx 先生 :
     我非常高兴地通知您,经过我公司的面试和讨论,我们一致认为您是我公司 互联网事业部 开发工程师 的合适人选。
根据公司的薪资福利政策,我们将给您提供以下薪酬福利待遇:
   (一) 月薪(税前):
         试用期xxxx元, 转正后xxxx元
         附加信息:
         试用期3个月
         年终发放双薪。
         特别说明: 按照公司规定,月薪中的15~20%(视岗位性质而定)为浮动工资,将结合每月绩效成绩,在每季度末统一发放。
 (二)季度奖金:
         每季度结束,将根据当季度个人的业绩发放季度奖金。
   (三)年终奖金:
         每年度结束,将根据公司经营业绩和个人考核成绩,发放年终奖金。
  (四)员工福利:
         公司为员工办理社会保险,并为员工提供各项优厚福利,包括:带薪假期、节日费、员工婚育礼金等,并资助员工的各项活动。
       腾讯公司和谐的凯发天生赢家一触即发官网的文化氛围一定会让您感受到集体的温暖。
       (以上员工福利待遇信息为保密资料,请勿向公司内外的其他人员透露。同时公司禁止兼职,并严格要求ipr保护及竞业限制等)
        如接受我公司的offer,请回复邮件说明;如对offer有任何疑问,也请尽快回复邮件说明,或致电0755-86013388转7031人力资源部luis(刘德志)联系。
        此offer两周内有效。
        备注:此录用offer已确认了您的专业资格,如果您确认此录用offer,我司相关人员将通知您入职资格(体检、验证等)的审核事宜
。若入职资格的审核(体检、验证等)不符要求,此offer将自动取消。故提醒您在前任单位离职前,先与我司做入职资格(体检、验证等)的确认。
 
 
 
        此致!
 
                                                                      腾讯科技(深圳)有限公司
                                                                            2005-8-19
@import ;@import url(/uploads/css/css/cuteeditor.css);

emu 2012-08-27 19:21
]]>
学习了一下条件注释http://www.blogjava.net/emu/archive/2012/01/11/368358.htmlemuemuwed, 11 jan 2012 11:51:00 gmthttp://www.blogjava.net/emu/archive/2012/01/11/368358.htmlhttp://www.blogjava.net/emu/comments/368358.htmlhttp://www.blogjava.net/emu/archive/2012/01/11/368358.html#feedback1http://www.blogjava.net/emu/comments/commentrss/368358.htmlhttp://www.blogjava.net/emu/services/trackbacks/368358.html

 ie看不到,非ie才看得到 


emu 2012-01-11 19:51
]]>
多年来头一回用到tdchttp://www.blogjava.net/emu/archive/2011/12/30/367568.htmlemuemufri, 30 dec 2011 04:23:00 gmthttp://www.blogjava.net/emu/archive/2011/12/30/367568.htmlhttp://www.blogjava.net/emu/comments/367568.htmlhttp://www.blogjava.net/emu/archive/2011/12/30/367568.html#feedback0http://www.blogjava.net/emu/comments/commentrss/367568.htmlhttp://www.blogjava.net/emu/services/trackbacks/367568.html


拷贝出来以后居然是一个庞大的xml文本,咋看呢。突然想起来有个ie特性专门用来干这个的,可能快有10年没用了,查查手册,很容易就做出了个页面

<html>
<head>
<body>
<xml id="xxx"><default><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app905_905_50.png" size_bytes="1535" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app905_905_16.png" size_bytes="216" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app608_608_50.png" size_bytes="9619" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app502_502_50.png" size_bytes="4557" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app501_501_50.png" size_bytes="2639" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app389_389_50.png" size_bytes="2018" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app389_389_16.png" size_bytes="1250" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app381_381_50.png" size_bytes="9727" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app381_381_16.png" size_bytes="1216" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app375_375_50.png" size_bytes="3831" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app372_372_50.png" size_bytes="1748" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app372_372_16.png" size_bytes="582" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app371_371_50.png" size_bytes="3820" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app371_371_16.png" size_bytes="533" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app370_370_50.png" size_bytes="9097" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app367_367_50.png" size_bytes="6109" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app365_365_50.png" size_bytes="5383" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app364_364_50.png" size_bytes="1701" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app363_363_50.png" size_bytes="2357" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app361_361_50.png" size_bytes="1397" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app359_359_50.png" size_bytes="2723" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app356_356_50.png" size_bytes="3839" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app355_355_50.png" size_bytes="3495" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app354_354_50.png" size_bytes="5209" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app353_353_50.png" size_bytes="3696" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app353_353_16.png" size_bytes="583" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app350_350_50.png" size_bytes="4318" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app346_346_50.png" size_bytes="2256" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app345_345_50.png" size_bytes="3462" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app24341_24341_50.png" size_bytes="3096" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app24341_24341_16.png" size_bytes="793" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app201_201_50.png" size_bytes="3426" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app201_201_16.png" size_bytes="452" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app11165_11165_50.png" size_bytes="3747" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:34 gmt (expires)"/><networkactivity url="http://ctc.qzonestyle.gtimg.cn/qzonestyle/act/qzone_app_img/app11165_11165_16.png" size_bytes="1939" total_s="0.00" mime="image/png" cache_expiration="30 dec 2011 04:04:28 gmt (expires)"/>default>xml>

<table datasrc= "#xxx" cellspacing=1 bgcolor=black style="font-size:13px">
<thead bgcolor=white> 
<tr> 
<th>cache_expirationth> 
<th>urlth> 
<th>size_bytesth> 
<th>imgth> 
tr> 
thead> 
<tbody bgcolor=white> 
<tr> 
<td><span datafld="cache_expiration">span>td> 
<td><span datafld="url" style="width:600px;word-break:break-all">span>td> 
<td><span datafld="size_bytes">span>td> 
<td><datafld="url" target="_blank"><img datafld="url" />a>td> 
tr> 
tbody> 
table> 
body>
html>
出来的界面还是可以一看的







emu 2011-12-30 12:23
]]>
简单的文本描边函数,写着玩儿。http://www.blogjava.net/emu/archive/2011/09/15/358694.htmlemuemuthu, 15 sep 2011 06:04:00 gmthttp://www.blogjava.net/emu/archive/2011/09/15/358694.htmlhttp://www.blogjava.net/emu/comments/358694.htmlhttp://www.blogjava.net/emu/archive/2011/09/15/358694.html#feedback2http://www.blogjava.net/emu/comments/commentrss/358694.htmlhttp://www.blogjava.net/emu/services/trackbacks/358694.html<html>
<body>
<div style="height:100%; width:50%; background-color:black; position:absolute; left:0px; top:0px">div>
<div id="test" style="position:absolute;left:40%;top:120px; color:white;z-index:100">凯发k8网页登录主页 <b>日志b> <i>相册i> <u>留言板u> <font size="10">心情font> 音乐<pre>丹东韶关限价令引质疑:限价为躲限购
[部分城市出台楼市限价令被指变相抵制限购令] [19城市成交量下滑]
[四成房企业绩增长] [济青楼市大搞优惠] [杭州半数楼盘成交不足2成]
上海一员工班车侧翻 已致11人死13人伤
[6名危重患者中4人病情已趋稳定] [俞正声韩正指示全力抢救伤员]
药剂师曝购买鱼精蛋白被强制搭售另一药
上海地铁8号线早高峰出故障 乘客称3站开35分钟13:18
湖北省委巡视办否认接受贫困县“天价接待”07:12
西安一退休干部雇凶杀46岁情妇 4名嫌犯先后落网07:24
富人官员与无房者争抢 浙江上演经适房乌龙闹剧10:23
湖南郴州原副市长雷渊利:被情人弄得晕头转向10:35
市民买到发霉汉堡包 肯德基被判10倍赔偿09:02
李阳谈家暴承认恨妻子:当时把她头撞地上好多下
pre>div>

<script type="text/javascript">

script>

 
body>
html>


emu 2011-09-15 14:04
]]>
ie下对文件(图片)进行base64转换http://www.blogjava.net/emu/archive/2011/08/28/357431.htmlemuemusun, 28 aug 2011 04:11:00 gmthttp://www.blogjava.net/emu/archive/2011/08/28/357431.htmlhttp://www.blogjava.net/emu/comments/357431.htmlhttp://www.blogjava.net/emu/archive/2011/08/28/357431.html#feedback2http://www.blogjava.net/emu/comments/commentrss/357431.htmlhttp://www.blogjava.net/emu/services/trackbacks/357431.html在编写某个的时候,经常发现用户被一些莫名其妙的代理服务器所劫持以后,一个正常的文本请求却下载到了一个图片。这种log看多了以后sidney就开始投诉了,想搜集到用户那里收到的到底是个什么图片。

这个图片用户那里虽然可以看,但是要生成到log里面就要另外保存一个文件,如果要上传的话还要开发相应的图片上传功能,这就麻烦了。

当然还可以用eml或者mht的形式吧图片打包在log里面,这样图片就会以base64形式编码进去嵌在log的文本里面了。但是hta记得似乎控制save命令的时候不能制定mht格式(没试过),eml要依赖客户端有邮件客户端,还要能通过js操控,更麻烦。

因此最简单的看起来就是zishun写的《》方案了,只要把图片转成datauri,就可以很容易的把图片信息嵌入到页面里面并在现代浏览器里面展现。这个方案唯一的问题是,仅限非ie。

还好ie其实也有类似的功能,并且效率更高,唯一的问题是要依赖activex,不过这再hta里面就不算问题了。

ie下的图片文件(图片)base64编码代码是这样的:

<script language="javascript">

script>




emu 2011-08-28 12:11
]]>
mac os 10.7.1(lion) 下vmware fusion里的windows有时无法工作在nat模式下的问题http://www.blogjava.net/emu/archive/2011/08/27/357399.htmlemuemusat, 27 aug 2011 05:49:00 gmthttp://www.blogjava.net/emu/archive/2011/08/27/357399.htmlhttp://www.blogjava.net/emu/comments/357399.htmlhttp://www.blogjava.net/emu/archive/2011/08/27/357399.html#feedback0http://www.blogjava.net/emu/comments/commentrss/357399.htmlhttp://www.blogjava.net/emu/services/trackbacks/357399.html因为mac系统很稳定,很少需要启动,因此折腾很久都没想到这中windows年代最顺理成章的解决方式。

emu 2011-08-27 13:49
]]>
ie这个bug真是弱爆了http://www.blogjava.net/emu/archive/2011/08/08/355989.htmlemuemumon, 08 aug 2011 01:54:00 gmthttp://www.blogjava.net/emu/archive/2011/08/08/355989.htmlhttp://www.blogjava.net/emu/comments/355989.htmlhttp://www.blogjava.net/emu/archive/2011/08/08/355989.html#feedback3http://www.blogjava.net/emu/comments/commentrss/355989.htmlhttp://www.blogjava.net/emu/services/trackbacks/355989.html<html>
<body>
<script language="javascript">
var a="
body>
html>
这样一段代码在ie下面居然语法解析错误!实在是弱到不知道怎么说好了。
当然,下面这一段代码,也不出意外的在ie下挂掉了
<html>
<body>
<script language="javascript">
var a="";
alert(a);
script>
body>
html>


终于明白为啥editplus里面插入script标记的时候总是帮我加上 了,这俩货还真不能随便去掉。
<html>
<body>
<script language="javascript">

script>

body>
html>

这个就没事。


emu 2011-08-08 09:54
]]>
脚本绑定回调增强版:备用url可以失败重试http://www.blogjava.net/emu/archive/2011/07/19/354660.htmlemuemutue, 19 jul 2011 12:50:00 gmthttp://www.blogjava.net/emu/archive/2011/07/19/354660.htmlhttp://www.blogjava.net/emu/comments/354660.htmlhttp://www.blogjava.net/emu/archive/2011/07/19/354660.html#feedback0http://www.blogjava.net/emu/comments/commentrss/354660.htmlhttp://www.blogjava.net/emu/services/trackbacks/354660.html《脚本绑定回调》  进行了一些有趣的尝试,这些尝试现在在一些web产品中已经应用了好几年了。这两年随着海外用户的增多,用户情况的复杂化,凯发k8网页登录的服务部署也开始复杂化了,有一些用户访问a域名失败,访问b域名就可能很畅顺,另一些用户则相反。而且很多时候这并不是gslb这样的调度可以及时检测到和快速调整的,不由得想想,能不能进行失败重试呢?其实也很简单把4年前的代码改了一改,做了一个原理性的实验:

<html>
<head>
<script language="javascript">
var isie = !!window.activexobject;
var usefragment=false;
function loadjs(url,callback,errcallback,url2,url3){
    
if(isie){
        
if(usefragment){
           
var df = document.createdocumentfragment();    
            df.visitcountcallback 
= function(data){
                s.onreadystatechange
=null;
                df
=null;
                callback(data);
            }
            
var s = df.createelement("script");
            df.appendchild(s);
            s.onreadystatechange
=function (ec,cb,u2,u3){
                
return function(){
                    
if(s.readystate=="loaded") {
                        s.onreadystatechange
=null;
                        df
=null;
                        
if(!u2){
                            ec();
                        }
else{
                            loadjs(u2,cb,ec,u3)
                        }
                    }
                }
            }(errcallback,callback,url2,url3)
            s.src 
= url;
        }
else{
            
var i=new activexobject("htmlfile");
            i.open();
            i.parentwindow.visitcountcallback
=function(i){
                
return function(d){
                    i.parentwindow.errcallback
=null;
                    i
=null;
                    callback(d);
                }
            }(i);
            i.parentwindow.errcallback
=function(ec,cb,u2,u3){
                
return function(){
                    i.parentwindow.errcallback
=null;
                    i
=null;
                    
if(!u2){
                        ec();
                    }
else{
                        loadjs(u2,cb,ec,u3)
                    }
                }
            }(errcallback,callback,url2,url3)
            i.write(
""" url "\"><\/script>settimeout(\"errcallback()\",0)<\/script>")
            
if(i)i.close();//如果数据被cache,运行到这一行的时候有可能回调已经完成,窗口已经关闭。
        }
    }
else{
        
var i = document.createelement("iframe");    
        i.style.display
="none";
        i.callback
=function(o){
            callback(o);
            i.contentwindow.callback
=null;
            i.src
="about:blank"
            i.parentnode.removechild(i);
            i 
= null;
        };
        i.errcallback 
= function(ec,cb,u2,u3){
            
return function(){
                    
if(!u2){
                        ec();
                    }
else{
                        loadjs(u2,cb,ec,u3)
                    }
            }
        }(errcallback,callback,url2,url3);
        i.src
="javascript:\"<script>function visitcountcallback(data){frameelement.callback(data)};<\/script><script src='" url "'><\/script><script>settimeout('frameelement.errcallback()',0)<\/script>\"";
        document.body.appendchild(i);
    }
}

function init(){
    
var spans = document.getelementsbytagname("span");
    
for(var i=0;i<spans.length;i){
        
var id = spans[i].id;
        
var url = "http://g.qzone.qq.com/fcg-bin/cgi_emotion_list.fcg?uin=a"id;//故意制造错误引发重试
        var url2 = "http://g.qzone.qq.com/fcg-bin/cgi_emotion_list.fcg?uin=b"id;//故意再次制造错误引发重试
        var url3 = "http://g.qzone.qq.com/fcg-bin/cgi_emotion_list.fcg?uin="id;
        
var callback = function(id){ return function(data){
            document.getelementbyid(id).innerhtml 
= data.visitcount;
            }
        }(id);
        
var errcallback = function(id){ return function(){
            document.getelementbyid(id).innerhtml 
= "无法连接到服务器";
            }
        }(id);
        loadjs(url,callback,errcallback,url2,url3);
    }
}
script>
head>
<body onload="init()">
12345(非法帐号)的访问量:
<span id="12345">span><br>
123456 的访问量:
<span id="123456">span><br>
20050606 的访问量:
<span id="20050606">span><br>
body>
html>

故意在前两次请求中制造了错误,尝试到第三个url的时候才成功。

emu 2011-07-19 20:50
]]>
把css和js写到一个文件里面的增强版http://www.blogjava.net/emu/archive/2011/07/19/354642.htmlemuemutue, 19 jul 2011 08:12:00 gmthttp://www.blogjava.net/emu/archive/2011/07/19/354642.htmlhttp://www.blogjava.net/emu/comments/354642.htmlhttp://www.blogjava.net/emu/archive/2011/07/19/354642.html#feedback2http://www.blogjava.net/emu/comments/commentrss/354642.htmlhttp://www.blogjava.net/emu/services/trackbacks/354642.html原文链接

最早的方法发表在msdn上:

代码是像这样子的:


   document.__definegetter__(    
"cookie"
        
function(){ 
            
return this.c;
        } 
    ); 
    document.__definesetter__(    
"cookie"
        
function(stext){ 
            
this.c="hack : "stext; 
        } 
    );     
   document.__definegetter__(    
"domain"
        
function(){ 
            
return this.d;
        } 
    ); 
    document.__definesetter__(    
"domain"
        
function(stext){ 
            
this.d="hack : "stext; 
        } 
    );     
    document.cookie
="fake cookie";
    alert(document.cookie)
    document.domain
="fake domain"
    alert(document.domain)


document实际上已经成了一个傀儡,随便开发者摆弄了。因此我们做基于document.domain和document.cookie的一些对第三方判断时候要小心。

emu 2011-01-19 09:47
]]>
好像是第一次在公司外的论坛上公开演讲http://www.blogjava.net/emu/archive/2010/12/15/340824.htmlemuemuwed, 15 dec 2010 12:43:00 gmthttp://www.blogjava.net/emu/archive/2010/12/15/340824.htmlhttp://www.blogjava.net/emu/comments/340824.htmlhttp://www.blogjava.net/emu/archive/2010/12/15/340824.html#feedback4http://www.blogjava.net/emu/comments/commentrss/340824.htmlhttp://www.blogjava.net/emu/services/trackbacks/340824.html    终于讲完了,下午公司内进行了二次分享,应该这次的分享算功德圆满了。
    国庆刚回来,淘宝就透过yuni吹风过来,说velicity会议第一次在国内举行,希望我们去参与和分享。几乎是本能的想逃了,实在不知道站到那样一群完全陌生的人前面,要讲些什么,怎么讲。
    到了10月底,dowson老大安排下来了,要去讲一场,这下躲不掉了,只好开始琢磨。看了下velocity在美国的分享ppt,偏web前端,偏性能和体验优化,而且都是很实用的技术。话题倒是熟悉,但是考虑到去的都是很多标杆公司,大家做的事情都差不多,如果讲别人做过和正在做的事情,那就没意思了。所以现状就是,要发掘些别人没想到的、行之有效的优化点去分享一下。
    当时本来也在公司内试推错峰preload方案,技术上都ok了,效果相当给力,想法也够新颖。本来有点想藏私的,leichen和dowson都主张我们要更开放点,就决定放出来了。
    然后再发掘我们内部独创的秘籍,有一些已经用烂了,有一些优化点又太小,显得小家子气,都否决了,最后选中了用了好几年,比较稳定可靠,外面又还没怎么听说过的ldns域名矫正方案。
    随后就爆发了那场大家都知道的大战,公司在很多专业人士眼里的形象好像都有点变型了,也感觉到我们做的很多正面的事情太低调了,不为人知。讲点啥能又有用,又能改变在大家心中的负面形象呢?正好这一年比较关注信息无障碍,于是确定了第三个议题。
    接着就是准备ppt和演讲内容。还好上次参加bu技术峰会学习到一个很重要的经验,一个ppt只要反复改,自然会慢慢变好。于是确定了主体内容,先是做了个和word差不多的ppt,然后不停的设想,讲这个内容要怎么讲,哪些意思要怎么表达,用什么图案,用什么动画效果,说些什么话。以前内部审核了很多课程的经验,也起了很大作用。中间还产生了不少创意,比如现场发礼品,拍团队视频等,有一些后来用上了,一些就放弃了。这是个不错的广告机会,又找great制作了春田花花同学会的logo作为幻灯片母版,这样就不动声色的打了一小广告。为了方便老大审核,把要说的话都提前设计好放到备注里面去了。这样也好,不怕到时忘词了,这是有深刻的历史教训的。设计了两周,才终于敢发给dowson审核。dowson给了一些修改意见,接着改。
    然后就是约了研发管理部,打算用敏捷俱乐部或者大讲堂作为内部试讲。但是没想到约的太晚,居然没有办法在velocity之前讲。好吧,先拿velocity做试讲,呵呵当然不可能了,只能内部试讲。一直拖着直到最后一个周五,再也没法拖了,才把前端team的兄弟们拉过来听试讲。
    试讲真的很重要,试讲一遍暴露了很多问题,也收集到了很多改进建议。周末回家后接着改,改了以后投影到液晶电视上,自己对着一空沙发试讲,讲到哪里卡壳了又停下来,把内容理顺,慢慢的内容越来越顺了,又开始删除备注里面的文字,看看自己能不能记得住词。到嗓子哑的时候,终于有一点感觉了。想用相机录下来自己看一遍,没想到一对着镜头,立马就忘词,三番四次之后,相机也没电了,就作罢了,希望到时在现场不要像对着这个相机这么紧张就好了。
    到北京的两天,都专心听别人演讲,没怎么想起自己要讲的事情,到最后一天下午,终于丑媳妇要见公婆了,又觉得内容有点陌生了,还好是下午第三场,利用中午的时间又过了一下内容,还修改了下ppt。接下去,不想了,准备上场。
    辛苦的准备终于还是换来了回报。现场没怎么忘词,而且讲的太嗨了,忘了控制时间,小马提前过来打手势的时候才想起来。后面的内容赶了下时间,一些想好的台词和内容都跳过了,比如和视障用户交流的一些细节,在3q大战中视障用户的支持等。
    一开始讲的时候提到了两次steve souders,随后才看到他进场来听,呵呵可惜了,本来我的内容里面估计也只有他自己的名字他能听懂,他居然错过了。还好后面几次提到google,gmail,还有很多代码和图案,他居然一句话没听懂也津津有味的听完了。随后他还跑过来祝贺我,说我good work。我说你听得懂吗,他说听不懂,我就乐了,听不懂你good work个啥啊,他说,the audience。我当时确实有点不以为然了。
    没想到后来又再专门找到我,跟我解释,说我是真的从听众的反应中可以看到你good work。后来他回到米国后发了一篇博客http://www.stevesouders.com/blog/2010/12/10/velocity-china/comment-page-1/ ,提到“i had trouble following the talks that were only in chinese although slides that had code or charts are universal. but i could tell these were good speakers – they were at ease up on stage, they engaged the audience, and their slides looked good.”,呵呵,还好听众们给力,还好我往ppt上放了好些charts和code。








emu 2010-12-15 20:43
]]>
信息无障碍的修复脚本http://www.blogjava.net/emu/archive/2010/09/26/332999.htmlemuemusun, 26 sep 2010 13:37:00 gmthttp://www.blogjava.net/emu/archive/2010/09/26/332999.htmlhttp://www.blogjava.net/emu/comments/332999.htmlhttp://www.blogjava.net/emu/archive/2010/09/26/332999.html#feedback2http://www.blogjava.net/emu/comments/commentrss/332999.htmlhttp://www.blogjava.net/emu/services/trackbacks/332999.html onfocus="this.blur()"
这样就导致整个网站人为的变成有障碍网站了,任何无法使用鼠标的用户也就无法正常使用这个网站,因为键盘不能聚焦到超链接上。
修复这个问题很简单,用hidefocus或者style="outine:none"来代替onfocus="this.blur()"就好了,但是有的时候网站页面太多,全站修改代价就大了。这种情况下可以在网站的模板或者通用脚本上面插入以下一段脚本来解决问题:

settimeout(
    (
function(){
         
var a=document.getelementsbytagname("a");
         
var regblur=/^function ((anonymous)|(onfocus))?\((event)?\)\s*\{\s*(this\.)?blur\(\);?\s*\}$/;
         
var isie=("\v"=="v");
         
for(var i=0;i<a.length;i){
             
if(regblur.test(a[i].onfocus)){
                 
if(isie){
                      a[i].hidefocus
="true";
                 }
else{
                      a[i].style.outline
="none"
                 }
                 a[i].onfocus
=null;
             }
         }
    }),
1000)

是不是很简单啊。
这段代码对于opera浏览器不兼容,因为opera浏览器本身就不是一个信息无障碍的浏览器,没有视障用户用opera的,大家都来鄙视opera吧。

平安夜那天早上,晴天反馈说有一些网站不是直接写onfocus事件,而是用attachevent/addeventlistener方式写了恶心的this.blur()。这事咋整呢?没有拿到原来绑定上面的函数句柄,就不能detachevent啊。最终想了一个跟blur差不多一样恶心的hack:
<html>
 <head>
 
<body>
  
<href="#" onclick="alert('click1')">test1a>
  
<href="http://www.qq.com/" >qqa>
  
<href="http://www.baidu.com/" >baidua>
  
<script type="text/javascript">
  

  script>
 
body>
html>

这样可以解决大部分类似这样的问题,也可以代替上面的方案,不过有一些副作用。考虑到大多数情况下超链接标签内部的内容结构都比较简单,也不会有太多的内部事件绑定的情况,这段代码应该可以应付大多数情形了。

emu 2010-09-26 21:37
]]>
ipad惊魂http://www.blogjava.net/emu/archive/2010/06/26/324552.htmlemuemusat, 26 jun 2010 06:05:00 gmthttp://www.blogjava.net/emu/archive/2010/06/26/324552.htmlhttp://www.blogjava.net/emu/comments/324552.htmlhttp://www.blogjava.net/emu/archive/2010/06/26/324552.html#feedback3http://www.blogjava.net/emu/comments/commentrss/324552.htmlhttp://www.blogjava.net/emu/services/trackbacks/324552.html事后彪叔是这么评价的:“那些小偷也倒霉,抢个东西遇到深圳反扒队的。。。”。


6月11号

  • wwdc2010的最后一天。早上在web开发方面还有最后两个repeat的session,是nob hill会议室的《delivering audio and video using web standards》。听完后觉得,所有的演示都基于局域网内非常快速的网络速度,如果网络差的地方,会不会和那天jobs演示的时候一样,一下就杯具了呢?于是和苹果的工程师探讨了一下,在网络很差的时候能不能用脚本对音视频的缓冲进行更进一步的控制,以达成更好的效果。苹果的工程师回答是你可以用脚本控制buffer,不过还是觉得存疑了,没有试验环境也不好进一步探讨,算了,回来自己研究。


    (wwdc2010会场)

  • session结束后,中午还有个cnn的event。听完后决定和wang一起去金门大桥看看夕阳,来了这么多天还没去过呢。于是坐上了38l路公交车前往金门大桥。在车上忍不住又把ipad拿出来继续读没看完的rss feeds。车子沿着geary大街走,在polk和van ness街之间有个站,有很多人排队下车。


    (cnn的技术vp在演讲的时候喜欢放很多震撼画面)

  • 这个时候有个中等个子的黑人小伙慢腾腾的排着队从我面前经过,突然一伸手,抢了我的ipad就往车下跑。好家伙,公车抢夺,原来在旧金山也和在国内并无二致。我跳起来一伸手抓住黑人的夹克衣领往后一扯。不幸的是体重对比太悬殊了,自己反而被他带到车下来了。


    (车票)

    嗯,在这里要再三强调一下,本人接受过一段时间的自卫术训练,包括如何在这样的情形下与身材比自己大一圈的对手搏斗,我们都是有过若干预案的,比如偷袭(第一预案,当时不具备这个条件);寻找手持武器自卫(第二预案,除了被抢去的ipad,手里只剩一个单反相机了,作为摄影协会老会员,这个预案也必须否决);装疯(扑上去大喊大叫乱打一气,逮到机会就抱紧对手狠咬一口,从气势上吓懵对手————考虑到自己门牙打过补丁,咬人这招不到万不得已不用)。围观群众切勿效仿。


    (ipad确实是现在最好玩的成人玩具)

  • 于是采用了装疯预案,我一边大声不知道喊着啥,一边左手紧抓着对方的衣领,跟他贴身,让他右手被栏到我外面不能攻击我(期望他是右撇子),右手开始用力打他的胸腹部。他也用左手还击我。一个不小心,两个人都绊倒了。杯具了,他倒在我身上,我翻不过去,被他骑住了。于是我只好两只手都收回来,准备在他攻击的时候可以做保护动作,此时真正有点危险了,不料对方一发现这个疯子松手,立刻抓住机会疯狂逃窜。万幸。
    打斗太激烈,感觉到全身脱力,我继续在地上躺了几秒钟缓下劲。wang同学大概就是这个时候认为我被打懵了,呵呵。然后起身来检查一下,没有大碍,看看身边,ipad已经被摔碎了,可怜的小家伙。


    (ipad成这样了)

  • 这个时候的标准操作应该是等警察到场处理,不过我的护照和电脑都还在公车上,要是护照丢了问题就严重了,只好先回车上拿包。拿到包后心宽了一点,终于可以坐下来透口气了,没想到公车这时发动了,开往下个站,我只好安心在车上休息一下,顺便自拍一张看看脸上那里刮破了。
  • 坐了一会,和wang商量了一下,还是不去金门大桥了,于是下车去报案。很多国内的朋友英文聊天还可以,最怕就是和外国人打电话,听半天听不清楚,其实大多数移民国家的公众服务部门都有提供多语言的翻译服务的,在这种复杂情形下更没有必要去考验自己的英文水平。打通了911后,我直接就要求了中文翻译服务。在翻译到达之前和警官沟通了一下基本情情况,然后接下去就翻译接手了。
  • 描述完现场情形,警方问要不要派救护车。自己也是担心有内伤,去查一下也好,就让派了一个。911要求,在原地等候救护车和警察到场,在完成检查之前不可以喝水吃东西(怕有内伤会恶化)。如果外伤流血不止的话他们可以在电话里面提供紧急止血指导————此时我的血已经止住了。然后开始等救护车。
  • 等了不知道多久,越来越口渴,又打了一个911,对方说救护车已经在路上,请继续耐心等候。继续等吧。然后就看到在对面路口发生了一起斗殴事件,终于把警察吸引过来了。我于是过街给警察当面再报一次案。


    (对面的美国人民打成一片)

  • 女事主很郁闷,要求警察先处理她的事,警察指着我额头的伤口说,他伤的比你严重,所以要先处理他的。呵呵报案原来也有插队的。

  • 于是重新描述了一遍事情经过,警察通过对讲机呼叫了一番后,救护车终于姗姗来迟了。从来没躺过担架的,这下也体验到了。
  • 上救护车后,先等警察完成报案手续(也许还顺便验证一下我的护照号有没有登记案底?),把证件和我的案件case no给我。


    (案件编号)

  • 之后我先要求护士帮我联系保险公司。出门前特地把平安的海外联系电话存在了手机里面应急的,这下可以用上了吧?护士询问了保险公司的名称后去系统里面查了一下,后来好像查不到“ping an”这个公司,就先不管了,有什么费用等事后再找保险公司也可以的。


    (救护车内照片)

  • 送进医院以后,就不允许动相机了:((


    (病房内偷拍)

  • 医院的人都很友好,处理我这个case的医生护士几乎每个人都来问了一下我的情况,还有从哪里来的,然后表达一下同情,最后再welcome to ca或者welcome to sf,尽力在使我觉得自己是被关心,受重视并且受到欢迎的。

    (医院给病人套一个腕带,把我的名字拼错了。把写在名字前面的visa的issue place当成first name了)

  • 一个很瘦小的东方面孔的美女医生负责处理我的case。询问了一下发生什么事,在我身上各个可能受伤的位置挤按拍打,确定重点检查部位,问了一些药物过敏和近期服用药物的问题,太专业了,我的英文又不够用了。问我说哪种中文,我说普通话,然后就杯具了,等说普通话的医生等了好久,还是没等到。


    (处方)

  • 最后拉了香港医生阿may过来,问我能不能说广东话,我说也可以啊,医生也快崩溃了————怎么不早说。之后的沟通简单多了,可以用广东话。


    (医嘱)

  • 阿may把我扶上轮椅,推过去拍了两张x光,再推回来等结果。阿may悄悄跟我说,也不用联系我保险公司了,费用让受害人基金会出就好了。也是啊,在加州随便买点啥都要收我那么多税,搞了半天社会治安还这么差,施瓦辛格的这个钱当然不能帮他省了。我这时都快渴死了,还是不能喝水,继续忍着。


    (胸透x光片)

  • 忍到结果出来,好几张专业文档,关键内容好像都是我看不懂也听不懂的。阿may好像下班了,于是护士小姐又打了个三方通话的翻译服务电话,给我介绍我的情况:肋骨骨折。我吓了一大跳,让翻译再确认一下,是不是我们通常理解的骨折,护士很确定的说,骨折了,不需要特殊处理,几周就自愈了,这期间要用力深呼吸扩张胸部,对愈合有好处。如果骨折影响了呼吸,那就吃止痛药,然后继续用力深呼吸。


    医生好心要把一份文档打印成中文的给我看,:((

  • 挂了电话,我让护士再去问医生,我哪个骨头折了。医生过来给我说,右侧第8或者第9,轻微骨折。杯具了。
    给了我一个止痛药让我服下,然后给我一个止痛药处方让我自己去买其中的某一种止痛药。然后,我可以自己回酒店了,呵呵,这是给骨折病人的待遇嘛。


    (复诊提示)


    (医院只开方不卖药,但是对处方中的药物却提供了通俗易懂的说明。)


    (医院只开方不卖药,但是对处方中的药物却提供了通俗易懂的说明。)

  • 回到酒店,先上网,第一时间发微博消息。呵呵,信息时代啊。


    (回酒店第一时间发微博。这是旧金山时间11日晚上。)

  • 出去吃了个饭,买了瓶布洛芬回来,发现腾讯数码微博已经推了这个消息,腾讯网友已经在微博上回复不少消息了。有网友建议可以拿ipad去苹果店看看能不能修,我本来想着肯定不能修了,不过去看看也好。有很多网友质疑一台ipad值得这样冒险吗?这样冒险和黑人壮汉搏斗当然不是为了一台ipad这么简单,我尝试了在微博上解释一下,不过这真的对大家来说不是太好理解,算了。


    (微博截屏)

  • 也有网友说可以找jobs要台新的。呵呵,乔帮主前几天刚讲过个故事说有个小伙玩ipad吸引到了美女注意,我要是这事写封伊妹儿给乔帮主说说说,让他下回要说这事也顺便提醒一下大家ipad的魔力也会带来为危险,倒是不错。于是写了第一封信。这一天就算过去了。


    (微薄截屏)

    12号

  • 由于背部受伤,一个晚上无法翻身,睡的相当别扭,一大早就起来了。一上线,正好有同事找我,说苹果公司开发者关系部夏鹏正在设法联系我,于是和他们联系了一下,沟通了情况,夏鹏主动提出第二天送我去机场。完了带着ipad的尸体前往苹果店。

    (ipad尸体)

  • 苹果店的人看到ipad的尸体没有期待的那么意外,很公事公办的说要找工程师评估一下价格。过了一回评估价格出来了,维修费$269。又等了一下,大高个黑人工程师出来接待。一见面很例行公事的问了句how are you,我一下想起那个摔下山崖的中国留学生笑话呵呵,于是跟他讲,不好,被人抢劫,ipad砸成了这样,还把我打伤了(和警察讲述的时候要尽量描述细节,和其他美国人讲述的时候,却要刻意回避抢劫者的肤色问题,种族歧视在西方国家是极其敏感的问题)。大高个听到了以后一脸的心痛和惋惜的表情,换了个非常非常温柔的声音跟我说怎么会这样,这不应该发生在你身上。你等等,我进去和主管商量一下,看看能不能免你的维修费。我很惊讶,他们看起来完全没必要给我这样的优待啊。大高个说机器砸烂了不是你的错,看看你的伤口,坏人太坏了。
    趁着他们商量,我又用现场的mac上网发了两条微博。结果他们很快就商量完了,大高个出来说,我们免费给你换了。拿出来一份换机文件给我签署,然后从仓库给我拿了台新机出来。

    (换机协议)

     

  • 这真是意外之喜,我道了谢就走了,走出了好远才想起来,怎么没和大高个合个影,又回去找他合影。

    (网友普遍认为这个apple guy很帅)

  • 回到酒店,又给乔帮主发了第二封邮件,对苹果公司表示了一下感谢。后来很多人说苹果一台ipad就把我收买了。其实正是他们在表达关心和给予优待的时候的这种毫无目的,把我感动了一下。


    (第二封邮件)

  • 过了不久,居然收到了jobs的那封只有3个单词的回信。众所周知乔布斯轻易不回邮件,以至于有些果粉网友说这封回信比若干台ipad还有价值,还有很多人劝我打印装裱起来供着,或者打印到衣服上天天穿着,呵呵。


    (乔帮主的回邮)

  • 数码频道及时推了这个消息之后,我得以有幸见识到乔布斯的魅力所在。中国开发者被袭击的消息并没有多少人关注,但是乔布斯给中国开发者发了邮件的消息,一下大小网站纷纷转载,国外网站也出了新闻,连我在老家连乔布斯何许人都搞不清楚的父母,也很快就知道了这件事,为了免得他们担心,我本来打算回国后再跟他们说的,这下瞒不住了。

    13号

  • 早上9点半,苹果公司的陈梓桥和夏鹏准时到酒店来送我们去机场。



    (苹果公司的陈梓桥和夏鹏)

    14号
    早上把美国拍片的结果发给马医生看,马医生初步认为8、9肋骨轻微骨折,无错位。7肋骨可疑。
    下午重新排了片,刘主任分析结果,骨头问题不大,主要是软组织拉上,开了些中药,建议静养几天。



  • emu 2010-06-26 14:05
    ]]>
    弱视用户看到我们的页面是像这样的http://www.blogjava.net/emu/archive/2010/06/22/324139.htmlemuemutue, 22 jun 2010 03:33:00 gmthttp://www.blogjava.net/emu/archive/2010/06/22/324139.htmlhttp://www.blogjava.net/emu/comments/324139.htmlhttp://www.blogjava.net/emu/archive/2010/06/22/324139.html#feedback4http://www.blogjava.net/emu/comments/commentrss/324139.htmlhttp://www.blogjava.net/emu/services/trackbacks/324139.html看了苹果wwdc的无障碍设计部分,他们的开发人员就是这样来体验弱视用户的产品体验的,我们也来体验一下别人的痛苦吧。我们的页面有办法设计得让这群人也感受好一点吗,就像苹果正在做的

    emu 2010-06-22 11:33
    ]]>
    不可忽略的 cache-read time(缓存读取延迟时间) 瓶颈http://www.blogjava.net/emu/archive/2010/04/09/317898.htmlemuemufri, 09 apr 2010 14:58:00 gmthttp://www.blogjava.net/emu/archive/2010/04/09/317898.htmlhttp://www.blogjava.net/emu/comments/317898.htmlhttp://www.blogjava.net/emu/archive/2010/04/09/317898.html#feedback2http://www.blogjava.net/emu/comments/commentrss/317898.htmlhttp://www.blogjava.net/emu/services/trackbacks/317898.html小小和rizen尝试过定位一个cache-read耗费时间随机的变得很长的诡异问题,排除过了文件内容、文件类型、文件头等各种影响,但是很遗憾没有最终结论。emu那天看知道这个事情后猜测,会不会就是很简单的多个cache-read操作相互竞争堵塞导致的呢?这个其实很容易验证了。写了一个简单的小页面应用了一组图片,然后抓包重新打开页面,就看到下面这个图了:




    第一个cache-read耗时0.2秒多,第二个(并行发起)0.3秒多,第三个0.4秒多,接下去每个图片的耗时差不多都比上一个慢0.1秒以上。结论很明显了,并发的cache-read会相互堵塞,非常严重的相互堵塞。
    以上抓包是在ie6下完成的。在ie7和ie8下面情况要好一些,但是问题性质是相同的。
    很多我们曾经以为cache的非常好速度应该非常快的web应用,也许其实存在着严重的cache-read速度瓶颈而不为我们所知。
    网上没有搜到太多关于cache-read时间的文章,看来真是个盲点。

    凯发天生赢家一触即发官网的解决方案和网络延迟是类似的,减少cache-read请求,把多个小文件和小图片合并成大文件和大图片(而不要一厢情愿的以为小文件被浏览器缓存后会有很好的速度表现),区分优先级引用资源。还有一个可能有用的:交错的发起不可避免的异步动态网络请求和cache-read请求,让网络延迟和cache-read延迟时间叠加在一起,来节省用户实际要等待的时间。



    emu 2010-04-09 22:58
    ]]>
    ie6不能用gzip压缩脚本,一个流毒甚广的谣言http://www.blogjava.net/emu/archive/2010/03/31/317027.htmlemuemuwed, 31 mar 2010 03:37:00 gmthttp://www.blogjava.net/emu/archive/2010/03/31/317027.htmlhttp://www.blogjava.net/emu/comments/317027.htmlhttp://www.blogjava.net/emu/archive/2010/03/31/317027.html#feedback0http://www.blogjava.net/emu/comments/commentrss/317027.htmlhttp://www.blogjava.net/emu/services/trackbacks/317027.html  

    文章作者说“跑到微软那一查,给的答复让我吐血:do not enable http compression for the script files 请不要对脚本文件开启http压缩 只好在服务器端增加对浏览器的识别代码,如果是ie6,就不压缩脚本文件了 虽然脚本能运行了,可是用户体验就...  哎,我恨ie 6”

    唉,说啥好呢?

    真相是,微软的答复() 里面提供了两个凯发天生赢家一触即发官网的解决方案,其中第一个描述的稍微啰嗦了一点,被这个作者直接忽略掉了。第二个凯发天生赢家一触即发官网的解决方案只有一句话,显然更容易被读懂:

    to work around this problem, you can do either of the following:

    if you use a cache-control: no-cache http header to prevent the files from caching, remove that header. in some situations, if you substitute an expires http header, you do not trigger the problem.

    -or-

    do not enable http compression for the script files.


    emu虽然英文比较烂,四级老考不过,为了方便大家还是翻译一下吧,不然又该有人读不下去了。

      要规避此问题,你可以在下面两个方案中选一种:

        1.如果你使用了cache-control: no-cache 这个 http 头来防止文件被缓存,移除这个头就好了。有些情况下,如果你用一个expires头来代替(前面这个出问题的http头),(也可以起到相同作用而)不会触发这个问题。

        或者

        2.不要压缩脚本文件。

    个人建议还是考虑第一方案。

    本文作为前面一篇翻译文章《》的补充。

    emu 2010-03-31 11:37
    ]]>
    [翻译]加速javascript:dom操作优化http://www.blogjava.net/emu/archive/2010/03/01/314185.htmlemuemumon, 01 mar 2010 09:20:00 gmthttp://www.blogjava.net/emu/archive/2010/03/01/314185.htmlhttp://www.blogjava.net/emu/comments/314185.htmlhttp://www.blogjava.net/emu/archive/2010/03/01/314185.html#feedback4http://www.blogjava.net/emu/comments/commentrss/314185.htmlhttp://www.blogjava.net/emu/services/trackbacks/314185.html原文:《speeding up javascript: working with the dom》

    作者: keekim heng, google web developer

    在我们开发互联网富应用(ria)时,我们经常写一些javascript脚本来修改或者增加页面元素,这些工作最终是dom——或者说文档对象模型——来完成的,而我们的实现方式会影响到应用的响应速度。

    dom操作会导致浏览器重解析(reflow),这是浏览器的一个决定页面元素如何展现的计算过程。直接修改dom,修改元素的css样式,修改浏览器的窗口大小,都会触发重解析。读取元素的布局属性比如offsetheithe或者offsetwidth也会触发重解析。重解析需要花费计算时间,因此重解析触发的越少,应用就会越快。

    dom操作通常要不就是修改已经存在的页面上的元素,要不就是创建新的页面元素。下面的4种优化方案覆盖了修改和创建dom节点两种方式,帮助你减少触发浏览器重解析的次数。

    方案一:通过css类名切换来修改dom 

    这个方案让我们可以一次性修改一个元素和它的子元素的多个样式属性而只触发一次重解析。

    需求:

    (emu注:原文作者写到这里的时候脑子显然短路了一下,把后面的out-of-the-flow dom manipulation模式要解决的问题给摆到这里来了,不过从示范代码中很容易明白作者真正想描述的问题,因此emu就不照翻原文了)

    我们现在需要写一个函数来修改一个超链接的几个样式规则。要实现很简单,把这几个规则对应的属性逐一改了就好了。但是带来的问题是,每修改一个样式属性,都会导致一次页面的重解析。

    function selectanchor(element) {
      element.style.fontweight 
    = 'bold';
      element.style.textdecoration 
    = 'none';
      element.style.color 
    = '#000';
    }

     

    凯发天生赢家一触即发官网的解决方案

    要解决这个问题,我们可以先创建一个样式名,并且把要修改的样式规则都放到这个类名上,然后我们给超链接添加上这个新类名,就可以实现添加几个样式规则而只触发一次重解析了。这个模式还有个好处是也实现了表现和逻辑相分离。


     

    .selectedanchor {
      font
    -weight: bold;
      text
    -decoration: none;
      color: #
    000;
    }

    function selectanchor(element) {
      element.classname 
    = 'selectedanchor';
    }

    方案二:在非渲染区修改dom

    (emu注:作者在这里再次脑子短路,把documentfragment dom generation模式的介绍提前到这里来了,emu只好再次发挥一下)
    上一个方案解决的是修改一个超链接的问题,当一次需要对很多个超链接进行相同修改的时候,这个方案就可以大显身手了。

    需求

    需求是这样的,我们要写一个函数来修改一个指定元素的子元素中所有的超链接的样式名(classname)属性。要实现很简单,我们可以通过遍历每个超链接并且修改它们的样式名来完成任务。但是带来的问题就是,每修改一个超链接都会导致一次重解析。

    function updateallanchors(element, anchorclass) {
      
    var anchors = element.getelementsbytagname('a');
      
    for (var i = 0, length = anchors.length; i < length; i ) {
        anchors[i].classname 
    = anchorclass;
      }
    }

    凯发天生赢家一触即发官网的解决方案

    要解决这个问题,我们可以把被修改的指定元素从dom里面移除,再修改所有的超链接,然后在把这个元素插入回到它原来的位置上。为了完成这个复杂的操作,我们可以先写一个可重用的函数,它不但移除了这个dom节点,还返回了一个把元素插回到原来的位置的函数。

    /**
     * remove an element and provide a function that inserts it into its original position
     * @param element {element} the element to be temporarily removed
     * @return {function} a function that inserts the element into its original position
     *
    */
    function removetoinsertlater(element) {
      
    var parentnode = element.parentnode;
      
    var nextsibling = element.nextsibling;
      parentnode.removechild(element);
      
    return function() {
        
    if (nextsibling) {
          parentnode.insertbefore(element, nextsibling);
        } 
    else {
          parentnode.appendchild(element);
        }
      };
    }

    有了上面这个函数,现在我们就可以在一个不需要解析渲染的元素上面修改那些超链接了。这样只在移除和插入元素的时候各触发一次重解析。
    function updateallanchors(element, anchorclass) {
      
    var insertfunction = removetoinsertlater(element);
      
    var anchors = element.getelementsbytagname('a');
      
    for (var i = 0, length = anchors.length; i < length; i ) {
        anchors[i].classname 
    = anchorclass;
      }
      insertfunction();
    }

    方案三:一次性的dom元素生成

    这个方案让我们创建一个元素的过程只触发一次重解析。在创建完元素以后,先进行所有需要的修改,最后才把它插入到dom里面去就可以了

    需求

    需求是这样的,实现一个函数,往一个指定的父元素上插入一个超链接元素。这个函数要同时可以设置这个超链接的显示文字和样式类。我们可以这样做:创建元素,插入到dom里面,然后设置相应的属性。这就要触发3次重解析。

    function addanchor(parentelement, anchortext, anchorclass) {
      
    var element = document.createelement('a');
      parentelement.appendchild(element);
      element.innerhtml 
    = anchortext;
      element.classname 
    = anchorclass;
    }

    凯发天生赢家一触即发官网的解决方案

    很简单,我们只要把插入元素这个操作放到最后做,就可以只进行一次重解析了。


    function addanchor(parentelement, anchortext, anchorclass) {
      
    var element = document.createelement('a');
      element.innerhtml 
    = anchortext;
      element.classname 
    = anchorclass;
      parentelement.appendchild(element);
    }

    不过,要是我们想要插入很多个超链接到一个元素里面的话,那么这个做法还是有问题:每插入一个超链接还是要触发一次重解析。下一个方案可以解决这个问题。

    方案四:通过文档片段对象(documentfragment)创建一组元素

    这个方案允许我们创建并插入很多个元素而只触发一次重解析。要实现这点需要用到所谓的文档片段对象(documentfragment)。我们先在dom之外创建一个文档片段对象(这样它也就不需要解析和渲染),然后我们在文档片段对象中创建很多个元素,最后我们把这个文档片段对象中所有的元素一次性放到dom里面去,只触发一次重解析。

    需求


    我们要写一个函数,往一个指定的元素上面增加10个超链接。如果我们简单的直接插入10个超链接到元素上面,就会触发10次重解析。

    function addanchors(element) {
      
    var anchor;
      
    for (var i = 0; i < 10; i ) {
        anchor 
    = document.createelement('a');
        anchor.innerhtml 
    = 'test';
        element.appendchild(anchor);
      }
    }

    凯发天生赢家一触即发官网的解决方案

    要解决这个问题,我们要先创建一个文档片段对象,然后把每个新创建的超链接都插入到它里面去。当我们把文档片段对象用appendchild命令插入到指定的节点时,这个文档片段对象的所有子节点就一起被插入到指定的元素里面,而且只需要触发一次重解析。

    function addanchors(element) {
      
    var anchor, fragment = document.createdocumentfragment();
      
    for (var i = 0; i < 10; i ) {
        anchor 
    = document.createelement('a');
        anchor.innerhtml 
    = 'test';
        fragment.appendchild(anchor);
      }
      element.appendchild(fragment);
    }


    注意:如无特别声明,本文中引用的所有程序均不是google开发,也与google没有其他什么关系。这些程序引发的责任均由其开发者或者所有者自己承担,与google无关。

    emu 2010-03-01 17:20
    ]]>
    [翻译] 压缩,让网络更快http://www.blogjava.net/emu/archive/2010/02/18/313398.htmlemuemuthu, 18 feb 2010 09:00:00 gmthttp://www.blogjava.net/emu/archive/2010/02/18/313398.htmlhttp://www.blogjava.net/emu/comments/313398.htmlhttp://www.blogjava.net/emu/archive/2010/02/18/313398.html#feedback1http://www.blogjava.net/emu/comments/commentrss/313398.htmlhttp://www.blogjava.net/emu/services/trackbacks/313398.html阅读全文

    emu 2010-02-18 17:00
    ]]>
    谷歌的在线翻译api很好用哈哈http://www.blogjava.net/emu/archive/2010/02/15/313141.htmlemuemumon, 15 feb 2010 15:50:00 gmthttp://www.blogjava.net/emu/archive/2010/02/15/313141.htmlhttp://www.blogjava.net/emu/comments/313141.htmlhttp://www.blogjava.net/emu/archive/2010/02/15/313141.html#feedback0http://www.blogjava.net/emu/comments/commentrss/313141.htmlhttp://www.blogjava.net/emu/services/trackbacks/313141.htmldoctype html public "-//w3c//dtd xhtml 1.0 strict//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      
    <head>
        
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
        
    <title>google ajax language api - basic translationtitle>
        
    <script type="text/javascript" src="http://www.google.com/jsapi">script>
        
    <script type="text/javascript">

        google.load(
    "language""1");

        
    function initialize() {
          google.language.translate(
    "happy new year!""en""zh-cn"function(result) {
            
    if (!result.error) {
              
    var container = document.getelementbyid("translation");
              container.innerhtml 
    = result.translation;
            }
          });
        }
        google.setonloadcallback(initialize);

        
    script>
      
    head>
      
    <body>
        
    <div id="translation">div>
      
    body>
    html>

    emu 2010-02-15 23:50
    ]]>
    关于firefox下settimeout的诡异函数http://www.blogjava.net/emu/archive/2010/01/19/310127.htmlemuemutue, 19 jan 2010 11:51:00 gmthttp://www.blogjava.net/emu/archive/2010/01/19/310127.htmlhttp://www.blogjava.net/emu/comments/310127.htmlhttp://www.blogjava.net/emu/archive/2010/01/19/310127.html#feedback2http://www.blogjava.net/emu/comments/commentrss/310127.htmlhttp://www.blogjava.net/emu/services/trackbacks/310127.html这个问题了,当时也没有留心去好奇一下。今天jayyang有再提起,上mozilla查了一下,原来有的:
    lateness" argument

    functions invoked by settimeout are passed an extra "lateness" argument in mozilla, i.e., the lateness of the timeout in milliseconds.


    写个小脚本测试了一下,果然不错

    var delay=3000
    if(/firefox/i.test(navigator.useragent)){
        settimeout(test,delay)
        alert(
    "试试等一会再确认")
    }
    else{
        alert(
    "只有 firefox 浏览器支持 lateness 参数!")
    }
    function test(){
        
    var t=arguments[arguments.length-1]
        alert(
    "你点alert之前犹豫了"(t<2?"不到"delay:delayt)"毫秒")
    }


    emu 2010-01-19 19:51
    ]]>
    flash player往页面注入的脚本表现了adobe的临时工水平http://www.blogjava.net/emu/archive/2010/01/16/309769.htmlemuemusat, 16 jan 2010 05:09:00 gmthttp://www.blogjava.net/emu/archive/2010/01/16/309769.htmlhttp://www.blogjava.net/emu/comments/309769.htmlhttp://www.blogjava.net/emu/archive/2010/01/16/309769.html#feedback7http://www.blogjava.net/emu/comments/commentrss/309769.htmlhttp://www.blogjava.net/emu/services/trackbacks/309769.htmlfunction __flash__arraytoxml(obj) {
        
    var s = "";
        
    for (var i=0; i<obj.length; i) {
            s 
    = """   i   "\">"  __flash__toxml(obj[i])  "";
        }
        
    return s"";
    }
    function __flash__argumentstoxml(obj,index) {
        
    var s = "";
        
    for (var i=index; i<obj.length; i) {
            s 
    = __flash__toxml(obj[i]);
        }
        
    return s"";
    }
    function __flash__objecttoxml(obj) {
        
    var s = "";
    }
    function __flash__escapexml(s) {
        
    return s.replace(/&/g, "&").replace(/g, "<").replace(/>/g, ">").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
    }
    function __flash__toxml(value) {
       var type = typeof(value);
        if (type == 
    "string") {
            return 
    "<string>"   __flash__escapexml(value)   "string>";
        } else if (type == 
    "undefined") {
            return 
    "<undefined/>";
        } else if (type == 
    "number") {
            return 
    "<number>"   value   "number>";
        } else if (value == null) {
            return 
    "<null/>";
        } else if (type == 
    "boolean") {
            return value ? 
    "<true/>" : "<false/>";
        } else if (value instanceof date) {
            return 
    "<date>"   value.gettime()   "date>";
       } else if (value instanceof array) {
           return __flash__arraytoxml(value);
       } else if (type == 
    "object") {
           return __flash__objecttoxml(value);
       } else {
            return 
    "<null/>"; //???
        }
    }
    function __flash__addcallback(instance, name) {
      instance[name] = function () { 
        return eval(instance.callfunction(
    "<invoke name=\""name"\" returntype=\"javascript\">"   __flash__argumentstoxml(arguments,0)   "invoke>"));
      }
    }
    function __flash__removecallback(instance, name) {
      instance[name] = null;
    }

    啥都甭说了,看看上面这几个“ =”,已经把啥都说了。刚看到youyee同学定位到一个严重性能瓶颈并表情上面把这段flash往页面里面注入的代码贴出来的时候,emu简直无法相信。
    还好大家都是干这行的,在flash注入完上述脚本后再覆盖(一开始误为重载了,感谢等同学的)掉这几个函数并不为难,最多就是为之难受罢了。


    emu 2010-01-16 13:09
    ]]>
    ie8下对cookie的限制。http://www.blogjava.net/emu/archive/2009/10/29/300227.htmlemuemuthu, 29 oct 2009 10:50:00 gmthttp://www.blogjava.net/emu/archive/2009/10/29/300227.htmlhttp://www.blogjava.net/emu/comments/300227.htmlhttp://www.blogjava.net/emu/archive/2009/10/29/300227.html#feedback3http://www.blogjava.net/emu/comments/commentrss/300227.htmlhttp://www.blogjava.net/emu/services/trackbacks/300227.htmlemu测试了一下ie8,发现cookie的限制似乎比以前宽松多了。具体限制是:
    * 每个域名下允许50个cookie,超过了覆盖最早写入的cookie(或者说队列式管理,超过了第一个出队)
    * 同一个页面(和从这个页面发出的请求)子域、父域和根域各自有自己的50个cookie。
    * 单个cookie的总长度:cookiename cookievalue 附加信息(包括等号,空格,分号,domain,expires,path之类的)不能超过5k(最多5119bytes)
    * 同一个页面(和从这个页面发出的请求)子域、父域和根域的全部cookie的内容长度(cookiename cookievalue 等号,空格,分号)不能超过10k,否则全部变成httponly,无法用脚本访问 * 同一个页面(和从这个页面发出的请求)子域、父域和根域的全部cookie的内容长度(cookiename cookievalue 等号,空格,分号)不能超过50k。

    总而言之,cookie不是用来存数据的,能不用就别用。

    边做测试边些博客的后果是,由于不停的清空cookie把博客的登陆态清掉了,差点文章提交失败重新写呵呵

    emu 2009-10-29 18:50
    ]]>
    csdn sd2.0大会,与csdn社区网友合影http://www.blogjava.net/emu/archive/2009/10/24/299573.htmlemuemusat, 24 oct 2009 08:05:00 gmthttp://www.blogjava.net/emu/archive/2009/10/24/299573.htmlhttp://www.blogjava.net/emu/comments/299573.htmlhttp://www.blogjava.net/emu/archive/2009/10/24/299573.html#feedback2http://www.blogjava.net/emu/comments/commentrss/299573.htmlhttp://www.blogjava.net/emu/services/trackbacks/299573.html

    emu 2009-10-24 16:05
    ]]>
    白突发了回奇想http://www.blogjava.net/emu/archive/2009/08/26/292709.htmlemuemuwed, 26 aug 2009 11:27:00 gmthttp://www.blogjava.net/emu/archive/2009/08/26/292709.htmlhttp://www.blogjava.net/emu/comments/292709.htmlhttp://www.blogjava.net/emu/archive/2009/08/26/292709.html#feedback3http://www.blogjava.net/emu/comments/commentrss/292709.htmlhttp://www.blogjava.net/emu/services/trackbacks/292709.html 有一天突发奇想,用表单想指定的资源发起一个post请求会如何呢?众所周知post请求到的数据是不能cache的,那么如果这个请求指向指定的url,该url的cache是否也就应该跟着失效呢?
    说干就干,用 fiddler ie/firefox 模拟了一下整个过程,结果是令人失望的,post请求到的数据固然不会进入cache,也不会把相同url的cache资源给冲掉。重新打开页面的时候,还是显示post以前cache住的那份资源。
    看来还是只好冒死用xhr去清cache了。

    emu 2009-08-26 19:27
    ]]>
    ie8里,“about:”又回来了http://www.blogjava.net/emu/archive/2009/05/22/277277.htmlemuemufri, 22 may 2009 04:32:00 gmthttp://www.blogjava.net/emu/archive/2009/05/22/277277.htmlhttp://www.blogjava.net/emu/comments/277277.htmlhttp://www.blogjava.net/emu/archive/2009/05/22/277277.html#feedback5http://www.blogjava.net/emu/comments/commentrss/277277.htmlhttp://www.blogjava.net/emu/services/trackbacks/277277.html
    <iframe src="about:hello">iframe>

    当然还有这样的

    showmodaldialog("about:hello")


    在ie6.0.2600以后,大家就只好转向更兼容的写法了:

    <iframe src="javascript:"hello"">iframe>

    今天偶然发现,ie8正式版下面,久违的“about:”又可以显示和执行了呵呵。

    emu 2009-05-22 12:32
    ]]>
    我现在在哪?http://www.blogjava.net/emu/archive/2009/05/07/269353.htmlemuemuthu, 07 may 2009 02:38:00 gmthttp://www.blogjava.net/emu/archive/2009/05/07/269353.htmlhttp://www.blogjava.net/emu/comments/269353.htmlhttp://www.blogjava.net/emu/archive/2009/05/07/269353.html#feedback7http://www.blogjava.net/emu/comments/commentrss/269353.htmlhttp://www.blogjava.net/emu/services/trackbacks/269353.html

    emu 2009-05-07 10:38
    ]]>
    chrome浏览器第一次使用google gears组建的时候会有问题http://www.blogjava.net/emu/archive/2009/01/13/251099.htmlemuemutue, 13 jan 2009 03:46:00 gmthttp://www.blogjava.net/emu/archive/2009/01/13/251099.htmlhttp://www.blogjava.net/emu/comments/251099.htmlhttp://www.blogjava.net/emu/archive/2009/01/13/251099.html#feedback3http://www.blogjava.net/emu/comments/commentrss/251099.htmlhttp://www.blogjava.net/emu/services/trackbacks/251099.htmlhttp://qzone.qq.com/blog/286013388-1231818216

    使用谷歌浏览器(chrome)的时候,有的时候脚本程序会捕获到“uncaught typeerror: object # has no method 'create' ”这个错误,在chrome的用户论坛上也有人在问这个问题。

    这个错误应该是由于最新版的谷歌浏览器没有自带完整的google gears组件导致的。看起来最新版的chrome浏览器会在用户第一次使用gears组件的时候自动下载和安装该组件,而在安装成功以前我们虽然可以成功创建 application/x-googlegears 对象,却无法调用它的create方法创建任何有用的东西。

    这个时候其实没有太多的事情可以做,基本上我们我们只能检测这个对象的create接口是否存在,发现不存在的时候提示用户耐心等待,过一段时间后再刷新,或者下回再来看看,希望它已经自己安装好了。



    emu 2009-01-13 11:46
    ]]>
    打开qq空间速度飞快的方法http://www.blogjava.net/emu/archive/2009/01/11/250880.htmlemuemusun, 11 jan 2009 13:07:00 gmthttp://www.blogjava.net/emu/archive/2009/01/11/250880.htmlhttp://www.blogjava.net/emu/comments/250880.htmlhttp://www.blogjava.net/emu/archive/2009/01/11/250880.html#feedback1http://www.blogjava.net/emu/comments/commentrss/250880.htmlhttp://www.blogjava.net/emu/services/trackbacks/250880.html打开qq空间速度飞快的方法

    假如你是中国电信adsl上网的用户,在windows平台下试用ie浏览器访问qq空间,那么
    首先呢,就是访问 先把google gears装上(最新是0.5版)。有一些同学访问不了gears凯发k8网页登录主页或者由于某种原因安装不上google上的最新版gears,那么可以试试到

    上下载稍微旧一点的版本(0.4版)
    网上还有更旧的版本,但是emu就没有实验过了。
    然后呢,你就可以访问这个地址了:
    对于网通宽带的朋友,就要访问这个:
    而对于教育网的朋友,则要访问这个:
    点击“启用加速”,会有个gears提示,确认以后,等全部进度条走成绿色就好了,以后访问qq空间的时候就会自动的变得飞快。

    有几点小技巧:
    * google gears不是很稳定,有的时候进度条走着走着就卡住不走了,这个时候可以多点几下“启用加速”就好了。如果还是不行,可能是网络原因,也没有关系,不管它就可以了,google gears会在网络好的时候自己把没下载完的文件给补上的。
    * 如果不大确定你的上网环境(联通?有线宽屏?铁通?),或者笔记本经常抱来抱去上qq空间,那么不妨把电信、网通和教育网三个页面都访问一遍,分别启用加速,这样不管在什么环境下都可以确定获得最好的效果。
    * 如果你用的是firefox浏览器,也可以依照上面的操作。
    * 如果你用的是google的chrome浏览器,并且是1.0正式版以上的版本,那么它已经自带了一个比较稳定版本的gears,跳过安装gears这一步。但是chrome下面gears还是有时不十分稳定,虽然emu已经尽力做了兼容,在第一次使用的时候还是可能有点问题。
    * 如果用的不是windows系统,那么gears还有macos下的版本,支持safari()和firefox()和linux下的版本( 支持firefox),恭喜恭喜。不过到底用起来怎么样,emu也没试过。
    * 如果你用的居然是opera,就认命了吧。


    emu 2009-01-11 21:07
    ]]>
    分域名优化的时候要考虑备选ip的问题http://www.blogjava.net/emu/archive/2008/05/23/202357.htmlemuemufri, 23 may 2008 03:36:00 gmthttp://www.blogjava.net/emu/archive/2008/05/23/202357.htmlhttp://www.blogjava.net/emu/comments/202357.htmlhttp://www.blogjava.net/emu/archive/2008/05/23/202357.html#feedback5http://www.blogjava.net/emu/comments/commentrss/202357.htmlhttp://www.blogjava.net/emu/services/trackbacks/202357.html 但是在做网络应用的时候,我们的一个域名下面有的时候会有多个ip多台服务器,分布在不同的机房,这个时候浏览器会在可选的ip里面随机的选择一个ip。用nslookup可以看到可选的ip,用ping可以看到当前正在实用的ip。
    在多个ip的情况下,对具体的一个用户,往往是连接到某些ip特别快,而连接到某些ip就不怎么块。比如我现在有一个域名(和它的几个分域名),在深圳访问的时候有2个ip可以分,其中一个是深圳本地的服务器,一个是外地的服务器。这个时候如果页面打开需要用到的关键资源依赖于这个域名,那么分域名有可能对速度不是提高而是有反作用。
    因为这种情况下,慢的资源成为了瓶颈,变成是速度的决定因素。我本来有一半的机会是快的,一半的机会是慢的,如果现在分两个域名去下载关键资源,变成有1/4的机会是两个域名都分到深圳的服务器,可以有提高,而3/4的机会是有一个以上的域名分到外地的服务器,反而变慢了,这样提高的是少部分人的感受,而多数人的感受没有提升或者变的更差。如果简单的按照yahoo的优化建议分散到4个域名上,那么这个比例就变成1:15,更差了。
    因此分域名下载不能简单的绝对化的看待,要看实际应用场景做决定。

    emu 2008-05-23 11:36
    ]]>
    网站地图