也谈IE浏览器P3P隐私策略
作者:nunumick 发布时间:18 Nov 2011 分类: front-end
P3P是什么
P3P(Platform for Privacy Preferences Project)是W3C公布的一项隐私保护推荐标准,旨在为网上冲浪的Internet用户提供隐私保护。现在有越来越多的网站在消费者访问时,都会收集一些用户信息。制定P3P标准的出发点就是为了减轻消费者因网站收集个人信息所引发的对于隐私权可能受到侵犯的忧虑。P3P标准的构想是:Web 站点的隐私策略应该告之访问者该站点所收集的信息类型、信息将提供给哪些人、信息将被保留多少时间及其使用信息的方式,如站点应做诸如 “本网站将监测您所访问的页面以提高站点的使用率”或“本网站将尽可能为您提供更合适的广告”等申明。访问支持P3P网站的用户有权查看站点隐私报告,然后决定是否接受cookie或是否使用该网站。
为什么要了解P3P
W3C公布这项协议之后,仅IE系列浏览器支持该协议,一直从版本6至目前的版本9乃至以后版本都支持,IE浏览器设置里有一个隐私选项就是这个了,如图:
可以看到,隐私策略设置默认阻止不受信任的第三方网站的cookie。这里需要明白一点什么是“第三方”,这是词是相对的指代,举个例子:用户在浏览A网站域下的页面,A就是第一方,同一个进程里除A以外的就是第三方网站。假设是在浏览B网站,那B网站之外的就是第三方网站。简单理解:被嵌套或被引用的非同域网站即为第三方网站。如果按照IE浏览器的默认隐私协议,第三方的cookie设置会受到限制,会出现cookie拿不到的情况。
在当今复杂多样的web世界,网站页面之间互相引用、嵌套的情况多有发生,没准就会碰到A嵌套B,B的cookie设置实效的情况,当然,这种情况目前只会发生在IE浏览器下,不过没准以后chrome、firefox也发个支持p3p的版本出来,那世界就和谐了。
隐私策略设置有多个级别,最高级的情况是阻止所有一二三方的cookie,等于是禁用了cookie,这种情况下,会发生什么,大家都懂的。鉴于目前动荡的网络世界和IE浏览器的使用占比,P3P这个玩意儿还是很有必要去了解一下的。
P3P引发的问题
显然,能引发的问题就是网站被第三方后,页面无法正常拿到cookie或者session,导致页面功能失效。举个例子:
A域网站a页面:test-a.php(nunumick.me域)
A域网站b页面:test-b.php(nunumick.me域)
B域网站页面:test-main.php
A域页面被第三方,访问B域页面,预期结果是输出”hello p3p”,实际在IE浏览器会报php错误
解决方案
1.设置P3P头
给被嵌套、引用页面设置P3P header
需要注意的是,一定要在设置cookie或者session之前设置好P3P header。
2.使用隐私配置XML
延伸知识
下面是摘抄的一段Compact Policies的具体取值范围和设值含义。
Compact Policies
Compact policies are essentially summaries of P3P policies. They can be used by user agents to quickly get approximate information about P3P policies, therefore improving performance.
For an in-depth explanation of compact policies, we refer to the P3P1.0[4] specification. Here, we limit to stating the syntax:
compact-policy-field = CP="
compact-policy "
compact-policy = compact-token *(“ “ compact-token)
compact-token = compact-access | compact-disputes | compact-remedies | compact-non-identifiable | compact-purpose | compact-recipient | compact-retention | compact-categories | compact-test
compact-access = “NOI” | “ALL” | “CAO” | “IDC” | “OTI” | “NON” |
compact-disputes = “DSP”
compact-remedies = “COR” | “MON” | “LAW” |
compact-non-identifiable = “NID”
compact-purpose = “CUR” | “ADM” [creq] | “DEV” [creq] | “TAI” [creq] |
“PSA” [creq] | “PSD” [creq] | “IVA” [creq] | “IVD” [creq] |
“CON” [creq] | “HIS” [creq] | “TEL” [creq] | “OTP” [creq] |
creq = “a” | “i” | “o” |
compact-recipient = “OUR” | “DEL” [creq] | “SAM” [creq] | “UNR” [creq] |
“PUB” [creq] | “OTR” [creq] |
compact-retention = “NOR” | “STP” | “LEG” | “BUS” | “IND” |
compact-category = “PHY” | “ONL” | “UNI” | “PUR” | “FIN” | “COM” |
“NAV” | “INT” | “DEM” | “CNT” | “STA” | “POL” |
“HEA” | “PRE” | “LOC” | “GOV” | “OTC” |
compact-test = “TST”
延伸阅读
度量页面速度的几项指标
作者:nunumick 发布时间:23 Feb 2011 分类: front-end
1.TTFB(Time to First Byte)
TTFB-首字节时间,顾名思义,是指从客户端开始和服务端交互到服务端开始向客户端浏览器传输数据的时间(包括DNS、socket连接和请求响应时间),是能够反映服务端响应速度的重要指标。
网页重定向越多,TTFB越高,所以要减少重定向
TTFB优化:
2.TTSR(Time to Start Render)
TTSR-开始渲染时间,指某些非空元素开始在浏览器显示时的时间,这也是一项重要指标,即TTSR越短,用户越早浏览器中的内容,心理上的等待时间会越短。过多的CPU消耗会拖慢TTSR,所以网站中有大量图片和脚本往往会造成不良用户体验。
TTSR优化:
- 优化TTFB
- 降低客户端CPU消耗,即页面加载初期不要有大脚本运行,把JS脚本放到页面下方
- 使用效率较高的CSS选择器,避免使用CSS表达式
- 避免使用CSS滤镜
前端TTSR测试脚本:
在页面端无法简单测试出具体的TTSR,不过可以通过模拟脚本得到大概的时间,Firefox提供了一个MozAfterPaint事件,经测试,用于TTSR并不准确,如果有MozBeforePaint事件该有多好。
3.TTDC(Time to Document Complete)
TTDC-文档完成时间,指页面结束加载,可供用户进行操作的时间,等价于浏览器的onload事件触发点。TTDC是比较重要的性能优化对象,TTDC越低,页面加载速度越快,用户等待时间越短。
TTDC优化:
- 优化TTFB
- 优化TTSR
- 参考YSLOW优化最佳实践
- 优化首屏时间,将不必要的页面加载放到onload事件之后
####TTDC前端测试: 常见性能测试平台大多使用IE浏览器的DocumentComplete事件来度量TTDC,DocumentComplete事件触发时,页面的状态应是READYSTATE_COMPLETE,所以在页面中我们可以用JS脚本判断:
4.TTFL(Time to Fully Loaded)
TTFL-完全加载时间,指页面在onload之前和onload事件之后额外加载的内容所花费的时间的总和,即页面完完全全加载完毕消耗的总时间。
TTFL优化:
- 优化TTFB
- 优化TTSR
- 优化TTDC
- 延迟加载
- 异步加载
- 按需加载
标签:
wpo
,
javascript
<<< EOF
容易被忽略的JS脚本特性
作者:nunumick 发布时间:14 Feb 2011 分类: front-end
一、容易被忽略的局部变量
思考这段代码的执行结果。
执行后,看看是否和你想象的一致?
ok,这段代码里核心的知识点是 var a = a++,其中两个变量 a 都是匿名函数内部的局部变量,是同一个,和全局变量 a 是不一样的。
为什么?我们来看看ECMA规范对变量声明语句的定义:
Description
If the variable statement occurs inside a FunctionDeclaration, the
variables are defined with function-local scope in that function, as
described in s10.1.3. Otherwise, they are defined with global scope
(that is, they are created as members of the global object, as described
in 10.1.3) using property attributes { DontDelete }. Variables are
created when the execution scope is entered. A Block does not define a new
execution scope. Only Program and FunctionDeclaration produce a new
scope. Variables are initialised to undefined when created. A variable with
an Initialiser is assigned the value of its AssignmentExpression when the
VariableStatement is executed, not when the variable is created.
声明中提到:进入作用域环境后,变量就会被创建,并赋予初始值undefined。在变量声明语句执行时才会把赋值表达式的值指派给该变量,而并不是在该变量被创建时。
因此上面的代码可以等价于:
这样应该会更容易理解了。
二、容易被忽略的全局变量
这是玉伯几天前分享到的知识点,蛮有意义的,在此也做个分析。
首先,考虑执行结果为什么是:5。
ok,原因出在 var a = b = 5 这句。
为深入分析这个语句,我们继续要参照ECMA规范对声明语句的定义: var a = b = 5;等同为 var a; a = b = 5;两条语句,后者是赋值表达式,其在ECMA中的定义是这样的:
Simple Assignment ( = )
The production AssignmentExpression : LeftHandSideExpression =
AssignmentExpression is evaluated as follows:
1. Evaluate LeftHandSideExpression.
2. Evaluate AssignmentExpression.
3. Call GetValue(Result(2)).
4. Call PutValue(Result(1), Result(3)).
5. Return Result(3).
对于a = b = 5;先执行左边表达式 a,这是一个标识符表达式,根据规范第 10.1.4,其执行方式如下:
During execution, the syntactic production PrimaryExpression : Identifier
is evaluated using the following algorithm:
1. Get the next object in the scope chain. If there isn't one, go to step 5.
2. Call the [[HasProperty]] method of Result(1), passing the Identifier as
the property.
3. If Result(2) is true, return a value of type Reference whose base
object is Result(1) and whose property name is the Identifier.
4. Go to step 1.
5. Return a value of type Reference whose base object is null and whose
property name is the Identifier.
搜寻作用域链,找到最近的一个 a 的引用,很明显,在匿名函数内部作用域就可以找到,于是变量 a 确定下来。 接着再执行右边的表达式 b = 5 ,还是一个赋值表达式,重复赋值规则第一步,因为变量 b 在匿名函数环境内未声明过,所以接着去 window 全局环境下去找 window.b ,被隐式声明为全局变量,最后赋值为 5,根据规则第五步,表达式的结果也会再赋值给 a。最终达到 a 和 b 都为 5 ,区别是 a 是局部变量,而 b 是全局变量。
我们再来理一下 (function(){var a = b = 5})() 表达式内部整体的执行顺序:
1. 匿名函数内创建变量a;
2. 赋予初始值undefined;
3. 取得变量a的引用; //a
4. 取得变量b的引用; //window.b
5. 对数字5求值;
6. 赋值5给b的引用:window.b;
7. 返回b = 5的结果5给a的引用:a;
8. 返回a = 5的结果5;
很明显,中间的一个步骤使得变量 b 被声明为全局变量,明白之后,我们不难找到代码的优化点:只需将变量 b 显式声明为局部变量:
标签:
javascript
,
ecma
<<< EOF
Webkit的跨域安全问题
作者:nunumick 发布时间:12 Feb 2011 分类: front-end
在使用try catch处理iframe跨域产生的异常时,chrome和safari浏览器似乎不能正常运作:他们直接抛出了错误而没有抛出可供JS截获的异常。这里有个简单的测试页面:IE、火狐弹出”hello world”,而chrome,safari,opera毫无反应。
以下是小段测试代码(刻意修改domain,让父页面和子页面为不同域页面):
1.父页面代码:
2.子页面代码:
以上代码目的是尝试在访问异常时动态修改domain达到顺利访问,但webkit内核浏览器粗暴地报错而非抛出可截获的异常,其他浏览器均如期运行。
chrome错误信息:
据了解,采用此类try catch方式做安全可行性判断的并不只是个别现象,如DOJO
还有很多网友的反馈:chrome bug report
以上代码在chrome,safari,opera均不适用。
从webkit开发人员的讨论消息中看到,他们承认这个问题但并不情愿去改正,holly shit!
延伸阅读
标签:
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