Webkit的跨域安全问题

作者:nunumick 发布时间:12 Feb 2011 分类: front-end

在使用try catch处理iframe跨域产生的异常时,chrome和safari浏览器似乎不能正常运作:他们直接抛出了错误而没有抛出可供JS截获的异常。这里有个简单的测试页面:IE、火狐弹出”hello world”,而chrome,safari,opera毫无反应。

以下是小段测试代码(刻意修改domain,让父页面和子页面为不同域页面):

1.父页面代码:

<script>
    document.domain = "nunumick.me";
    function doTest(){
        alert('hello world');
    }
</script>
<iframe src="http://www.nunumick.me/lab/x-domain/webkit-test.html">
</iframe>

2.子页面代码:

<script>
    try{
        top.name;
    }catch(e){
        document.domain = 'nunumick.me';
        top.doTest();
    }
</script>

以上代码目的是尝试在访问异常时动态修改domain达到顺利访问,但webkit内核浏览器粗暴地报错而非抛出可截获的异常,其他浏览器均如期运行。

chrome错误信息:

chrome error

据了解,采用此类try catch方式做安全可行性判断的并不只是个别现象,如DOJO

try{
    //see if we can access the iframe's location
    //without a permission denied error
    var iframeSearch = _getSegment(iframeLoc.href, "?");
    //good, the iframe is same origin (no thrown exception)
    if(document.title != docTitle){
        //sync title of main window with title of iframe.
        docTitle = this.iframe.document.title = document.title;
    }
}catch(e){
    //permission denied - server cannot be reached.
    ifrOffline = true;
    console.error("dojo.hash: Error adding history
    entry. Server unreachable.");
}

再如FCKeditor

try{
if ( (/fcksource=true/i).test( window.top.location.search ) )
   sFile = 'fckeditor.original.html' ;
}
catch (e) { /* Ignore it. Much probably we are insi
de a FRAME where the "top" is in another domain (security error). */
}

还有很多网友的反馈:chrome bug report

以上代码在chrome,safari,opera均不适用。

从webkit开发人员的讨论消息中看到,他们承认这个问题但并不情愿去改正,holly shit!

延伸阅读

  1. html5 security location
  2. webkit dev lists

标签: webkit , crossdomain , javascript , browser
<<< EOF

【转】面试开发人员的有效方法

作者:nunumick 发布时间:12 Jan 2011 分类: career

要雇佣开发者时,传统的面试方法显得力不从心,这是必须要面对的现实。你会读简历、电话面试、技术面试、文化适应面试、各方面测试,最后,你基本上跟着自己的感觉走,雇佣了你认为优秀的人,即使这样,也会经常看走眼。情况不太理想,这是因为开发者属于技术性工人,谈话反应不出他或她对所在领域有多精通。

为什么传统面试方法不行呢?

当你要求别人跟你一起面试时,你会给他们多少准备时间呢?很可能没多少(如果你会给多于5分钟的时间,说明你准备的比较充分),所以和你一起面试的考官只是在前往面试地点的路上匆忙浏览一下简历,所以我也不会继续讨论提前准备一些问题这个话题。提前准备到这种程度,你又怎么可能了解到简历之外的信息呢?即使大家准备了一段时间,他们培训过多少关于面试技巧的知识呢?和其他一样,面试也是一名技术,即便有丰富的阅历,也不一定能成一名面试官。人们提问题时问不到点子上,即使能够提出比较好的问题,他们也不知道该从回答里得到哪些信息。

所以,缺少培训以及准备不足是个问题,但你可以克服这些困难,但这有助于改善状况吗?收效甚微,那么在面试过程中你应该测试求职者的哪些能力呢?下面列出了一些:

学习能力
人际交往/团队工作能力(可以在面试过程之外测试)
能够在现实与设计之间折中
工作到最后一刻
在公司需要的技术方面有足够的经验
对其他技术也有所涉猎
等等

所有你能做的就是提问,然后相信求职者所回答的。面试过程中,不要提这样的说法:很多优秀的人在某个职位上都没做好。你要放弃他们吗?如果你能面试到一个你信任的人推荐的面试者,你应该感到很幸运,但是,如果遇不到,怎么办呢?很幸运,可以很简单地去甄别,让求职者展示一下他们的技术,让他们写点代码看看。

不!不是在白板上写代码

在白板或纸上写代码,即使是在笔记本电脑上进行5分钟的测试,这些都不是真正的编码。你需要把这些技术人员放到他们所处的位置上,然后后退,观察他们。观察他们如何工作、如何跟别人交流,以及别人如何跟他们交流。 Seth Godin提出,我们需要跟我们的潜在雇员共事几个月,这听起来不错,但有点不切实际,而且也不需要观察那么长时间。让我说,一天时间就能让你得到足够的信息,然后做出正确决定。如果你心里有中意的求职者,把他们安排到你的团队里工作一天,观察他们是否合适,而不是再对他们进行一轮又一轮的面试。这一天的工作结束之后,把你的团队成员召集起来,然后让他们告诉你是否应该雇佣这个人。(编注:如果觉得这样的代价很大,可以尝试《通过电子邮件发现优秀的程序员》。)

这种方法的优势很明显。你不需要假设他们适应你的企业文化(或者做多选择心里分析),你只须测试一下。如果你信任的人乐意跟这个人一起工作,那么你直接就能发现,毕竟,这也是他们必须要做的事。你可以大体了解一下你的求职者技术的深度和广度。你可以测试出他们驾驭新系统的能力,以及对事情的领悟能力。所有你所做的这些都在一个远不如面试正式的气氛中进行,而且在这种气氛中,开发者可以感到很舒服。如果面试官们让那些候选雇员提前准备一下,效果会更明显。

用创新来吸引有创意的人

很显然,在最终雇佣一个人之前,我们不能要求他一整天都在工作或者面试。但是,我们真的不能吗?为什么不可以呢?难道在你的公司不是一个有足够吸引力的地方吗?如果不是,那么尽快改进,然后执行雇用程序。如果要求别人放弃很多休息时间而带来的诸多不便让你感到很不安,那么想想当你意识到你已经雇用一个蹩脚的雇员6个月之后,已经太晚了,这会给你带来更多的不便。创意无限你才能吸引那些喜欢充满创造力的氛围的人才,人们才会乐意花一整天的时间,因为他们可以经历一次有趣又与众不同的面试。你的公司应该成为这种公司:可以吸引到那些你想雇佣的人才。你的面试过程以及雇佣方式是第一步,要不要采取那种有效的方式完全取决于你。

原文链接:http://www.skorks.com/2009/09/the-best-way-to-interview-a-developer/
中文翻译:http://www.jobbole.com/entry.php/448

标签: interview
<<< EOF

前端优化技巧之img sprites

作者:nunumick 发布时间:04 Jan 2011 分类: front-end

背景知识:

css sprites是前端开发必须掌握的一项优化技巧,此技巧的意义常被作为基础题放入面试环节。可以这么说:不知道css sprites的前端不是好前端。

html:

<div class="sample">某某示例</div>

css:

.sample{
    height:50px;
    width:50px;
    overflow:hidden;
    background:url(../sprites/img-sprites.png) no-repeat -50px -10px;
    line-height:99em;
}

而img sprites可以说是css sprites的变种,此技巧的使用最早可以追溯到2007年,主要用于提升网页的可用性。img sprites与css sprites两者原理上基本是一致的,区别在于img sprites把css样式表中的背景图挪到了标签中

html:

<div class="sample">
    <img src="../sprites/img-sprites.png" alt="某某示例" />
</div>

css:

.sample{
    height:50px;
    width:50px;
    overflow:hidden;
}
.sample img{
    margin:-10px 0 0 -50px;
}

还可以使用clip属性来控制图片显示区域

那么,使用img sprites有哪些好处呢?

一、img sprites 的优势:

1.支持windows高对比度显示模式

windows用户如果把显示设置成高对比度模式,则在一些特定浏览器下(Opera),css sprites就会显的面目全非,而img sprites可以避免此类问题。

2.打印终端友好

css sprites背景图无法被打印,而img sprites则可以,这一点我力挺img sprites。

3.SEO友好

使用img sprites,搜索爬虫可以抓到网页中的图片,只需要给图片加上相应的alt注释,用户也可以理解搜索到的图片。

4.顺序加载

浏览器的渲染和操作顺序大致如下:

  1. HTML解析完毕。
  2. 外部脚本和样式表加载完毕。
  3. 脚本在文档内解析并执行。
  4. HTML DOM 完全构造起来。
  5. 图片和外部内容加载。
  6. 网页完成加载。

需要注意一点是:背景图和普通图片还不一样,背景图要比普通图片加载的顺序来的靠后,这有一篇实验性文章可以说明这一点,而换成img sprites则可以按照实际的顺序进行加载。

5.语义化

该是图片的时候就是图片,比如LOGO,比如网站介绍性图片

6.提升可用性

当用户禁用图片时,至少可以通过alt注释知道网页要讲些什么

二、img sprites 的劣势:

  1. 图片过大时会阻塞网页加载进度
  2. 右键另存为图片,会将整张sprites图下载到电脑里
  3. 开发成本比css sprites要高,需要权衡性价比

其实css sprites在1、2两方面多少也存在着同样的问题。

三、如何权衡

  1. 图片较大或是纯修饰图片的,用css sprites会更好一些
  2. 有具体意义的图片或者需要较快出现图片或者需要照顾特殊用户群体和打印终端的,采用img sprites则会更好
  3. 在一些较重要的图片,如网站LOGO,我认为更适合做单独的一张图片,css sprites和img sprites两者都不用。虽然多了一个HTTP请求,换之带来的是对用户体验和SEO的友好。

标签: css , sprites
<<< EOF

JavaScript学习笔记-详解in运算符

作者:nunumick 发布时间:31 Dec 2010 分类: front-end

in运算符是javascript语言中比较特殊的一个,可以单独使用作为判断运算符,也常被用于for…in循环中遍历对象属性

一、判断

语法

prop in objectName

如果objectName指向的对象中含有prop这个属性或者键值,in运算符会返回true。

var arr = ['one','two','three','four'];
arr.five = '5';
0 in arr;//true
'one' in arr; //false,只可判断数组的键值
'five' in arr;//true,'five'是arr对象的属性
'length' in arr;//true

原型链

in运算符会在整个原型链上查询给定的prop属性

Object.prototype.sayHello = 'hello,world';
var foo = new Object();
'sayHello' in foo;//true;
'toString' in foo;//true;
'hasOwnProperty' in foo;//true;

对象与字面量

in运算符在对待某些特定类型(String,Number)的对象和字面量时显得不尽相同

var sayHelloObj = new String('hello,world');
var sayHello = 'hello,world';
var numObj = new Number(1);
var num = 1;

'toString' in sayHelloObj; //true
'toString' in sayHello; //类型错误

'toString' in numObj;//true
'toString' in num;//类型错误

究其原因,在MDN找到这样一段关于String对象和字面量转换的介绍,似乎可以解释这个原因:

Because JavaScript automatically converts between string primitives and String objects, you can call any of the methods of the String object on a string primitive. JavaScript automatically converts the string primitive to a temporary String object, calls the method, then discards the temporary String object. For example, you can use the String.length property on a string primitive created from a string literal

试着这样理解:因为in是运算符而非一个方法(method),所以无法让string字面量自动转换成String对象,又因为in运算符待查询方不是对象而是一个字符串(按老道Douglas的说法,只是object-like的类型),所以报类型错误。

二、遍历

很常用到的for…in循环语句,此语句中的in需要遵循另外一套语法规范:

for (variable in object)
statement

与单独使用in作为运算符不同,for…in循环语句只遍历用户自定义的属性,包括原型链上的自定义属性,而不会遍历内置(build-in)的属性,如toString。

对象

function Bird(){
    this.wings = 2;
    this.feet = 4;
    this.flyable = true;
}
var chicken = new Bird();
chicken.flyable = false;
for(var p in chicken){
    alert('chicken.' + p + '=' + chicken[p]);
}

String对象,经过测试Firefox,Chrome,Opera,Safari浏览器都是给出了注释中的结果,只有IE浏览器只给出’more’和’world’

function Bird(){
var str = new String('hello');
str.more = 'world';
for(var p in str){
    alert(p);//'more',0,1,2,3,4
    alert(str[p]);//'world','h','e','l','l','o'
}

字面量

遍历数组字面量的键值和属性

var arr = ['one','two','three','four'];
arr.five = 'five';
for(var p in arr){
    alert(arr[p]);//'one','two','three','four','five'
}

遍历string字面量,虽说单独在string字面量前面使用in运算符会报类型错误,不过下面的代码却能够正常运行,此时IE浏览器是毫无声息

var str = 'hello';
str.more = 'world';
for(var p in str){
    alert(p);//0,1,2,3,4
    alert(str[p]);//'h','e','l','l','o'
}

综上

ECMA虽然有这方面的规范,但浏览器之间还是存在着差异,鉴于此,并不推荐用for…in去遍历字符串,也不推荐拿去遍历数组(如例子所示,为数组加上自定义属性,遍历就会被搞乱)

在遍历对象方面,我们还可以使用对象的内置方法hasOwnProperty()排除原型链上的属性,进一步加快遍历速度,提升性能

function each( object, callback, args ){
    var prop;
    for( prop in object ){
        if( object.hasOwnProperty( i ) ){
            callback.apply( prop, args );
        }
    }
}

标签: javascript , operator
<<< EOF

博客转移到Typecho平台

作者:nunumick 发布时间:30 Dec 2010 分类: blog

作为码农,崇尚简约是美,wordpress对于我来说显的过于笨重,很多功能用不上,不需要,界面繁杂不友好。加之godaddy的空间速度慢如乌龟,博客页面更是不堪重负。看到朋友转移到简洁小巧的typecho,感觉很好,心里痒痒。

Type,有打字的意思,博客这个东西,正是一个让我们通过打字,在网络上表达自己的平台。
Echo,意思是回声、反馈、共鸣,也是PHP里最常见、最重要的函数,相信大部分PHP爱好者都是
从echo ‘Hello,world!’;开始自己的PHP编程之路的。
将这两个词合并在一起,就有了Typecho,我们期待着越来越多的人使用我们开发的程序,
也期待着越来越多的人加入到开源的行列里。
大家一起来,Typecho )))))))))))))))))))))

熟悉的hello,world,熟悉的echo,typecho的名字就充满了php的味道,甚是诱人。

前不久,我的新博客地址nunumick.me开张,正是转移平台的好时机,于是我利用中午休息时间做了转移,整个过程用时很短,typecho不愧是轻量级的。

由于godaddy空间apache配置的不给力,typecho安装成功后一直无法访问除首页之外的其他页面,费了我不少力气。

幸好有互联网和搜索引擎,仅仅靠copy和paste一些现成的代码就解决了难题: 在blog根目录 index.php 的 Typecho_Plugin::factory(‘index.php’)->begin(); 这行前面加上

$baseInfo = @explode('?', $_SERVER['REQUEST_URI'], 2);
if (is_array($baseInfo))
{
        $_SERVER['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
        $_SERVER['PATH_INFO'] = $baseInfo[0];
        unset($_GET);
        if ($baseInfo[1])
        {
                $getInfo = @explode('&', $baseInfo[1]);
                foreach ($getInfo as $v)
                {
                        $getInfo2 = @explode('=', $v);
                        $_GET[$getInfo2[0]] = $getInfo2[1];
                }
        }
}

如果启用了伪静态,则还需要修改 .htaccess 文件:

RewriteEngine On
RewriteBase /
RewriteRule index(\.)php/(.*) /index.php?/$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]

如果不是很明白htaccess的语法规则,可以参考htaccess语法教程

OK,成功进入后台,恢复数据,自定义设置,感受typecho的简洁和亲切,国人就应该支持国人的产品!

Enjoy!

标签: wordpress , typecho , php , htaccess
<<< EOF