Archive for the ‘前端技术’ Category

今天我神奇的发现,现阶段基于webkit内核的浏览器(Chrome、Safari等),通过document.domain,可以将domain设置到最后一级(最后一个点之后的内容)。举例说明:

  1. www.qgy18.com可以设置domain为“com”,不能是“cn”等其它内容;
  2. www.aoao.org.cn可以设置domain为“cn”,不能是“com”等其它内容;
  3. www.imququ.com.(注意后面的.)可以设置domain为“”,不能是“com”、“cn”等等其它内容;

这能干嘛呢?显然,只要两个域名有同样的domain,就可以轻易的跨域通讯了。那么在webkit下,只要两个域名后缀一样,例如都为com或者都为空,通过这种方式可以轻松跨域了。

我把这个问题发在QWrap群里讨论,有人说这是Webkit内核的一个feature,用来方便开发者实现跨大域。我认为这是bug,因为,虽说很少有人会把自己的网站domain设置为com,但是对于黑客来说,他如果在你网站做这件事情,那你的网站跟他的站点就成一家人了,这种行为也不容易被发现。

Read the rest of this entry »

随着智能手机的普及,大家已经习惯随手拍点照片传网上了。有时候传上去的照片方向会不对,甚至还有脑袋朝下的情况。为此,各大微博不约而同的给照片增加左右旋转的功能。这样能解决问题,但我们是否能更进一步,自动选择正确的照片方向呢?刚好最近我们有类似的场景,本文就讨论下这个问题。

实际上,数码设备拍摄照片时,会把许多属性附加在照片文件里,这些属性构成了大家常说的Exif信息。访问我的相册会发现照片下也有对应的Exif信息。Exif中有个Orientation字段,用来存放照片方向,这就是我们需要的,看下它的定义:

Read the rest of this entry »

什么是浏览器模式和文本模式?

经常使用IE开发者工具的同学,肯定见过浏览器模式和文本模式,对于这两个名词,综合相关文档解释如下:

浏览器模式(Browser Mode),用于切换IE针对该网页的默认文本模式、对不同版本浏览器的条件注释解析、决定请求头里userAgent的值。它在浏览器发出请求之前就已经确定,网站没有办法修改这个值。它代表的是用户以何种浏览器访问网站。IE9支持下列浏览器模式:

  userAgent 默认文本模式
IE7 MSIE 7.0 IE7标准
IE8 MSIE 8.0 && Trident/4.0 IE8标准
IE9 MSIE 9.0 && Trident/5.0 IE9标准
IE9兼容性 MSIE 7.0 && Trident/5.0 IE7标准

IE9兼容性模式与IE7模式的区别是:前者在UA里加上了Trident版本,后者和IE7完全一致无Trident标识;IE8中,IE9兼容性模式对应为IE8兼容性模式,UA里Trident版本为4.0,其他没变化。另,IE8中没有IE9模式

Read the rest of this entry »

事情经过是这样的:今天某同学用Matrix滤镜实现了IE下的一个旋转效果,但在IE6、7下页面样式全部被搞乱掉,滤镜之后的CSS样式完全没生效。剥离无关代码后类似于这样:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Jerry Qu's HTML document</title>
    <style type="text/css">
    #img {
      filter:progid:DXImageTransform.Microsoft.Matrix(M11=-0.707,M12=-0.707,M21=0.707,M22=-0.707,SizingMethod='auto expand');
    }
    body {color:red;}
    </style>
  </head>
  <body>
    <img id="img" src="http://st.imququ.com/uploads/2011/07/ququ_1_1_1.jpg" />这行文字应该是红色的。
  </body>
</html>

用IE6或7打开这个页面,可以看到滤镜之后定义的样式没有生效。

Read the rest of this entry »

上一篇博客提到09年初WED团队开发的浏览器环境检测工具时,忘记说这个是aoao同学的创意了。不过没关系,据说他又在秘密规划新版本了,再据说新版要增加的DNS解析时间计算已经开发完成,点上面那个链接就可以抢先体验。。。

好吧,参加过11年Velocity大会的同学应该都知道facebook那个算DNS解析时间的方法了,像我这种穷人家孩子参加不起VC大会的,主办方很厚道的提供有PPT可供观看。看完PPT觉得不过瘾,还是来动手实战下吧。

首先看原理:

a <= <random number>

t1  http://a-doppler.facebook.com/test_pixel?HTTP1.0&t=1&size=0k
t2  http://a-doppler.facebook.com/test_pixel?HTTP1.1&t=2&size=0k
t3  http://a-doppler.facebook.com/test_pixel?HTTP1.1&t=3&size=0k
t4  http://a-doppler.facebook.com/test_pixel?HTTP1.1&t=4&size=10k

t1 = DNS + New Connection +RTT
t2 = New Connection + RTT
t3 = RTT
10k /(t4–t3)~TCP bandwidth

(来源:《MobilePerformanceVelocity2011.pdf》 by DavidWei.)

Read the rest of this entry »

今天看到某大牛之前写的某段代码里,用到了"| 0"这种写法将字符串取整。这本来没什么,很多人都这样做,但他那段代码里处理的是一个时间戳。如:

"1325239449538" | 0;

结果是-1905444926,这显然不是我们想要的。这个问题产生的原因是:A | B是将A、B先ToInt32再运算,返回结果是32位符号型整数。只要A超过2147483647,也就是231-1,就杯具了。

另一个常用的parseInt函数也容易发生杯具,如:

parseInt(0.0000001);

在大部分浏览器上,结果是1(新版firefox会得到0),这也显然不符合预期。原因是parseInt(A)第一步会执行ToString(A)。上面的例子中,0.0000001会转成"1e-7",后面的事情应该都知道的。

本文链接:http://www.imququ.com/post/89.html

--EOF--

围观过QWrap的同学可能会注意到其官方的特性介绍里有这么一条:

提供YUI2一样的静态方法库,同时又用所谓的Helper规范来做到真正的绝对静态,让组件开发者可以发布出无依赖的组件。

其中,组件无依赖化,也就是核心库定制这个特性,在某些场景下还是非常有用的。QWrap提供了相应的工具来实现,JK这篇文章有详细说明。只是这个工具藏得很深没多少人知道,好酒也怕巷子深~ 最近我在这个工具的基础上增加了代码选取的功能,一起再给大家介绍下。

首先,访问代码选取小工具页面。

第一步,选择要用到的方法。这一步比较好理解,例如要用到数组迭代就选中ArrayH下的forEach,需要格式化日期功能就选择DateH下的format,依此类推。特别的,Browser(浏览器UA相关)、Selector、CustEvent(自定义事件)这三个模块目前是不能拆分的,只能按模块选择,并不能细化到每个方法。

Read the rest of this entry »

先来句题外话,最开始Ajax应该是用来特指用XMLHttpRequest传输数据这门技术,但就像最近大家把一切web新技术都归到html5名下一样,现在一切异步获取数据的手段都被人称之为Ajax。

由于JavaScript同源策略的存在,跨域数据交互是个老生常谈的话题了。网上相关文章很多,不过随着时间的推移和浏览器的更新,一部分解决方案已经不适用了,同时也出现了一些更好的方法。抛开纯服务器Proxy这种跟前端没什么关系的方案不说,这里简单总结下常见的其他几种方式。

JSONP

JSONP是最常见的跨域数据交互的方式,原理是html的script标签可以加载并执行其他域JS文件。站点B把要提供的数据作为参数传给一个站点A定义的全局函数,站点A引用这个文件就可以跨域获取数据了,A站还可以把少量参数放在script标签的src里提交给B站。外链JS这种方案只支持GET,受IE下url长度不能超过2083个字节的限制和出于安全考虑,一般不用来提交数据。

有人通过后端Proxy使得这种方式可以获取任意页面内容,还增加了对POST的支持,如:

<script type="text/javascript" src="http://www.ajax-cross-domain.com/cgi-bin/ACD/ACD.js?uri=(http://www.google.com)"></script>
<script type="text/javascript">
	alert(ACD.responseText);
</script>
<script type="text/javascript" src="http://www.ajax-cross-domain.com/cgi-bin/ACD/ACD.js?uri=(http://216.92.131.147/dotserv/ACD/runit/post.cgi)&method=post&postdata=(name=fred&email=fred@fred.com)"></script>
<script type="text/javascript">
	alert(ACD.responseText);
</script>

实际上这个方案是借助后端把任意页面输出为JS变量,后端根据url中相关标识来决定请求方式和参数,并不能解决大数据提交问题。

原生表单+Redirect+Callback

原生的form表单支持提交数据到其他域,我们只需要把form的target指向页面上的隐藏iframe,那就实现了无刷新提交,剩下的问题就是怎么获取提交后的结果。例如站点A表单提交数据到站点B,通常我们会在站点B处理完请求,重定向到站点A下某个Proxy页面,并在url带上参数标识处理结果。接着,A站下的Proxy页面就可以解析url参数,传给父页面的Callback函数来处理了。

Read the rest of this entry »

大家都知道FaceBook发明了BigPipe,把页面分为多个PageLet来加载,让服务端运算与客户端加载并行进行,使得页面可交互时间往前提了不少。我这里不谈如何实现BigPipe,而是分析下FaceBook如何处理不支持JavaScript的场景。

对于不支持BP的浏览器,服务端必须一次生成所有HTML,每个模块用到的JS和CSS也需要合并。那怎么让服务器尽早知道客户端不支持JS呢?FaceBook的办法是在BP模式的HTML里加上了NoScript标签和Meta跳转:

<noscript><meta http-equiv="refresh" content="0; URL=/?_fb_noscript=1" /></noscript>

这样,如果用户的浏览器不支持JS,那访问FaceBook的任何一个页面,都会重定向原URL,并带上_fb_noscript=1这个参数。接着,服务端根据这个标记就可以按照非BP模式输出完整的页面。

如果用户访问每一个页面都需要多一次重定向,是不是很浪费时间和带宽呢?确实如此!FaceBook已经考虑到这个问题了:服务端在收到_fb_noscript=1标记时,会给客户端设置noscript=1的Cookie,这样下次请求哪怕没有URL参数标记,服务端也可以根据Cookie标记适配到非BP模式。

但是,如果客户端突然又支持JS了呢?这种情况多半是在测试,理论上继续用非BP模式也没什么问题,但FaceBook还是很厚道的处理了这种情况:在非BP模式的HTML里有这么一段JS:

Read the rest of this entry »

最近换了份工作,来到一个全新的前端团队。新团队有些同学可能之前全身心投入到业务开发中,对代码Review的必要性和基本流程了解不多,有滴同学可能还没听过CodeReview这个名词。

代码Review其实就是把代码贴出来让大家批斗的一个过程,对提高团队整体代码水平(如代码规范性、可维护性、设计合理性等)都有很大帮助。前端代码直接面向最终用户,代码Review更是应该作为一个专业前端团队必不可少的一环。

怎么组织一场代码Review呢?我觉得可以从下面几方面来考虑:

  • 前置条件:一系列合理的规范文档。没有规范就没有Review标准,没有统一标准Review就变得随意、收益不明显、不可持续;
  • 被Review的人:可以根据项目实际情况轮流担任。一般新同学被Review出来的问题会多点,但并不代表老同学的代码不需要被Review。代码Review本来就是一个互相纠正、互相学习的过程,每个人都有自己的亮点和不足;
  • 被Review的代码:最好不要直接从Git/svn同步,而是让被Review者自己挑选合适的代码放上去。这个合适有两方面需要考虑:一是代码规模必须适量;二是要挑典型代码,去掉关联不大或功能类似的代码段;
  • Review的形式和周期:考虑到实际情况,每次代码Review都指定至少一个主Review人,提前看代码并收集change set。然后召集组内成员在会议室看投影,一个个点来讨论change set,记录讨论过程与结论。这样做成本比较高,所以Review频率不要高于一周一次;
  • Review平台:Review重要的是协作和交流、分享与学习,工具是其次。挑选一个合适的Review平台,不是要用工具取代人的职责,只是让Review代码能更方便,能归档查询所有Review历史。

特别说下Review平台。之前我们WED团队使用的是Trac下名为PeerReview的插件,由于Trac比较重量级,而且这边已经有现成的各种类似平台,再搭一套Trac有点重复建设。开源的Review系统试过几个,如groogle,感觉和理想中还差那么一些。于是自己花了几天时间,写了个简单的Review系统,下面是两张截图:

Read the rest of this entry »

关于我

JerryQu,当前从事前端开发,@中国北京
这里是我随便记录东西的地方~
需要找我,我的联系方式在这里»
查找QGYWebIM相关信息,请点这里»

  • PPanda sftp如何同步本地文件夹呢?
  • dron 嗯!太有用了,终于完美找回 EditPlus 的感觉了。
  • 袁源 还真的是这样。其实挺佩服微软的呀~就是都太不完善了
  • 三水清 类似功能可以使用fiddler,http://ming.sinaapp.com/?p=218
  • 呆呆 非常感谢~话说我现在想把weinre变成一个服务器,就是我在电脑上修改了,手机上访问可以直接,不知道[...]
  • 困扰了我好几天的问题,不过最后还是让我解决了,要早让我看见这个文章该多好啊,那我也不用烦恼那么久了~[...]
  • hoowolf 非常感谢你的工作!!!
  • welefen 恩,去年我们在新首页导航精准下线的时候也遇到过,当时还做了对用户影响的数据评估和分析。
  • 唠叨下 我们这边测试的时候是在刚做完 preload 后的系统上测试的,就跟刚装完操作系统后一样干净。怎么说[...]
  • gust 我是在ubuntu11.10环境下
  • gust 想用google浏览器的话可以这样 webbrowser.get('/usr/bin/google[...]
  • jin 怎么zenCoding的缩写设置呢,类似editplus下的acp配置
  • Jerry Qu @Feather,确实Shadow是基于Weinre封装的。在我这里也很慢,因为它连的是http:/[...]
  • Feather 谢谢分享,其实Adobe的Shadow产品貌似也是用这个原理来做的,不过shadow封装好,比较方便[...]
  • i am bug 感谢屈屈!