javascript 中parent和window的概念

在多层iframe嵌套时,parent和window如何理解?

window和parent在IE和Firefox中的实现有些不太一样。

 

w3c中有如下叙述:http://www.w3schools.com/jsref/obj_window.asp

Window Object

The window object represents an open window in a browser.

If a document contain frames (<frame> or <iframe> tags), the browser creates one window object for the HTML document, and one additional window object for each frame.

 

1. 既然每个frame有自己的window,window.name为什么还一样?

 

 

参考资料:

http://www.w3schools.com/jsref/obj_navigator.asp

http://www.w3school.com.cn/htmldom/dom_obj_window.asp

 

关于无src的iframe的使用

这里演示了一个没有src的iframe,它存在的意义在于:

写在其内部的元素的样式不会受到父页面的css的影响。
使用”move”按钮,可以将form表单所在的浮层移动到iframe中,也可以从iframe中移动出来
通过移动前后的比较,你可以发现input元素的样式发生了变化,因为外部页面设置了样式
这里面还有一个有意思的现象:
我让iframe去appendChild一个iframe外部的div时,并不是复制一个div,而是直接移动div到目标位置(更像是我有些外行)

关于登录浮层的开发

缘起

最近考虑开发一个登录浮层,可以放置到任何的页面,使用方只需要引用JS,并对JS添加几项配置就可以使用。

遇到的问题:

1. 如果浮层中使用iframe的方式,则存在内外通信的跨域问题(可能这个比较方便解决)

2. 如果不适用iframe的方式,则很容易导致浮层和页面中的css的冲突(这个后患无穷)

 

分析:

考察了一下腾讯的登录浮层,果然,他们是使用了iframe的方式,我想,可能iframe会有一些问题,但这应该是正道

 

需要解决的问题:

1. 浮层内部如何与浮层外部通信,如:登录成功事件、关闭登录浮层事件。

 

思考:

对于一个没有src属性的iframe,其内部的脚本执行和父页面之间存在跨域问题吗?如果没有跨域问题,则完全可以使用外部的js来绘制iframe里面的内容

关于web页面的JS错误监控

一般来讲,server端的脚本错误可以通过日志来方便的监控,而web页面上的错误经常是通过用户反馈才知道的,甚至会因为环境问题无法重现而难以解决,下面介绍一种常见的web页面错误的收集、监控方法。

1. 对JS错误的监控,示例脚本:

或许你已经看到了,这哪里是“示例”,这分明就是从线上环境中抄来的;恩,不错,但是适合不适合自己,还需斟酌,这里只介绍一种思想; 举一反三一下,或许在你的强大的try…catch.. 之下,window.onerror基本没机会触发了,那么也可以在自己的catch中添加类似的逻辑,将意外的错误上传到服务器上,然后对这种错误信息做监控

2. 当然,不仅仅针对JS,比如flash等,也可以使用类似的手段

3. 我想,这应该是一个基础的功能,应该有一个基础的类库来支持,比如,badjs.qq.com 似乎是专门来做这个事情的,应该有专门的人来负责“上报错误脚本”的开发和上报错误的监控

 

从HTTP协议到PHP中的cookie 编码

 

实例脚本:

 

请求和响应:

输出:

结论:

  1. setcookie函数会对cookie的value做一次urlencode编码
  2. 客户端(浏览器)不会对cookie的value做任何转码
  3. PHP的server端在解析提交的cookie时,会对cookie的value做一次urldecode然后初始化到$_COOKIE数组中

延伸:

如果使用setrawcookie函数,对cookie的value不做urlencode,那么value中如果含有 “;”,则上行cookie的编码会是什么样的呢?(因为上行的多个cookie是靠”;”开分隔的)

测试代码:

结果:

 

结论:

1. 设置cookie时,cookie的value是需要urlencode的; 毕竟http协议中cookie的设置如下:

cookie的属性之间使用”;” 来分隔的,如果cookie的value中含有 “;” ,自然也不会当做value的一部分的

2. PHP对于上行的cookie也是做urldecode的(尽管多个cookie之间的分隔符不是”&”)

3.  从协议层不难看出,cookie名字也是不能有特殊字符的,就像value中不能函数特殊字符一样

 

PHP中setcookie的部分实现:

从上面实现,我们不难发现,cookie名字中不能含有哪些字符;而对于cookie值,如果允许编码,则允许任意字符了

 

注意

PHP中setcookie对value的编码使用的是urlencode:

1. urlencode对有些字符是不编码的,有些时候会带来不必要的麻烦

2. urlencode会将空格编码为’+’,而有些解码函数如JS中的 unescape 、decodeURIComponent 并不会将 ‘+’ 解码为空格的,于是cookie中的’hello world’,使用JS从cookie中取出后就会成为’hello+world’

针对上面两个问题,建议:

1. 自己对cookie值做rawurlencode,使用setrawcookie来设置cookie

2. 自己对cookie值做rawurlencode,使用header函数来set-cookie

 

关于cron

cron程序

cron程序用来周期性地启动某些进程。它通常使用crond程序或者crontab程序进行控制,你可以简单地把crond守护进程和crontab程序看成一个,它们实际是用同样的方式执行的,只是方法不同。

要使用cron的功能,首先需要启动crond守护进程,   我们先介绍最简单的设置cron的办法。在Linux系统中,cron程序的行为由/etc/crontab文件控制,这个文件由若干个部分组成,一般情 况下,它包括设置执行参数的部分和实际的命令部分,我们用一个示意性的crontab文件来描述它的基本格式:

#/etc/crontab

SHELL=/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin

MAILTO=root

HOME=/

在一串#上面的部分是为cron设置的环境,这个环境现在设置的是使用bash。其他行的意义一目了然。

cron的执行语句,每个语句占据一行,代表一个作业设置,行可以由6个或者7个栏目构成,7个栏目的语句格式是

[分钟] [小时] [日期] [月份] [周中的天数] [用户] [命令]      分钟和小时就是你准备执行命令的钟点,日期则指的是月中的日期

例如,一个典型的crontab登记项可以写成      30 4 1 * * root rm -f /var/log/httpd/*

这里的五个时间域有两个是*号,表示通配,因此这里的时间域就是每个月的1日早晨4:30,执行命令的用户身份是root,后面的部分是命令。连起 来就是在每个月的1日4:30自动删除/var/log/httpd下面的所有文件。容易看出问题发生在同时设置日期和星期几的两个域的时候。例如,0 0 13 * 5到底是代表每月的13日零点,还是每星期五的零点,或者必须是“黑色的星期五”才能执行呢?     答案是这样的一个写法代表所有的13日加上所有的星期五都会执行这个命令。这一点是比较容易出现问题的地方。

当你书写crontab文件时一定要注意,crond程序设计得比较成问题,它要求每行必须以回车结尾:你可以在文件末尾加上几个空行,这不会影响crond运行,但是如果你的最后一行忘了加上一个回车,那么crond程序将会忽略这一行,不去执行对应的作业。

每个时间域都可以使用列表来设置多个值,例如,你想让某个任务在每天的2:00,4: 00和6:00运行,那么时间域的部分应该写成      0 2,4,6 * * *      另外一个常用的cron时间域符号是/,它代表“每”。举个例子来说,你想让某个任务每隔5分钟执行一次,当然你可以在分钟域中用 0,5,10,15,20,….55来处理这个问题, 但是你也可以用这样的方式来设置时间域:     */5 * * * *     在时间域中,可以使用减号代表集合,例如,在小时域中的8-12和8,9,10,11,12是等价的。

也可以用六个域来表示crontab表项,这时用户身份项被省略,其他各项的含义不变。     一般情况下,只要crond守护进程在运行中,它会每隔1分钟察看一次/etc/crontab文件,因此你修改了crontab文件之后不需要重新启动 crond程序,只要简单地等待就可以发现crond会刷新它的列表。如果发生了什么不寻常的事情,或者crond程序没有完成你设定的作业,你可以察看 /var/log/cron文件查阅问题的原因。     上面解释的是系统的cron作业设置,每个用户还可以设置自己的cron作业表。比如, 我是某个用户,我想每隔5分钟在虚拟控制台1上显示一下当前时间,那么我可以建立这样的一个文件:      */5 * * * * date > /dev/tty1      同样,回车符是不可缺少的。假设文件名字为testcron,然后用crontab命令设置作业表:      crontab testcron      这样就可以了。      同样,任何一个用户都可以建立自己的cron文件。

要察看某个用户自己设置的作业,使用crontab命令的-l-u 开关:      # crontab -l

要清除自己的作业列表,使用crontab -r命令。

crontab执行相关的权限文件有两个,分别是/etc/cron.allow和/etc/cron.deny。如果cron.allow文件存 在,系统试图从中读出可以执行crontab命令的用户名字,其他的用户(除了root)都无法使用这个命令;否则,如果cron.allow文件不存 在,系统将寻找/etc/cron.deny文件,如果存在的话,那么系统认为所有人都可以执行crontab命令,除了列在/etc /cron.deny中的用户;最后,如果这两个文件都不存在,除了root以外的其他用户将无法使用crontab命令.

at守护进程

at程序是另外一种管理作业的工具,与crond程序不同,at调度程序是设置程序在设定好的某个时刻执行,但是只执行一次。 要使用at调度程序,必须首先启动atd守护进程,语法很简单:      #/usr/sbin/atd      然后就可以用at命令调度作业了,例如,对我们想在三个小时之后, 也就是1:00开始这个进程(假设进程的名字是cpu_killer),那么,可以这样使用at命令:      $ at now + 3 hours      这里设置程序将在三个小时之后执行,也可以使用明确的时间:      $ at 1:00 kill_cpu     无论哪一种情况,都会出现at命令的提示符:      at>      可以输入命令:      at> kill_cpu      at>      在这个提示符下可以输入多个命令,直到你按下^D组合键:      at>       warning: commands will be executed using /bin/sh      job 2 at 2000-12-31 04:00       at命令的一般语法是      at [时间] [命令]      时间参数是启动命令的时间。at命令认识类似下面形式的命令:      1930 December 5   表示12月5日晚上19点30分      19:30 December 5 跟刚才的形式等效      11:00 pm    表示夜间23:00      11:00 P   同上      now + 1 week   从现在开始一周以后      4:30 Tuesday next week 下星期二4:30      5:15 12/05/2000         2000年12月5日早晨5:15        不是每个用户都可以使用at调度作业。

与at执行相关的权限文件有两个,分别是/etc/at.allow和/etc/at.deny。如果at.allow文件存在,系统试图从中读出 可以执行at命令的用户名字,其他的用户(除了root)都无法使用这个命令;否则,如果at.allow文件不存在,系统将寻找/etc /at.deny文件,如果存在的话,那么系统认为所有人都可以执 行at命令,除了列在/etc/at.deny中的用户;最后,如果这两个文件都不存在,除了root以外的其他用户将无法使用at命令。

 

摘自: http://hi.baidu.com/ezrax/blog/item/51caca06c7cc857f03088145.html

 

更多参考: http://zh.wikipedia.org/wiki/CRON

测试例子:

该cron是 2012年7月30号21点08分设置的,当日星期一,执行文件内容如下:

Mon Jul 30 21:09:01 CST 2012
Mon Jul 30 21:10:01 CST 2012
Mon Jul 30 21:11:01 CST 2012

 

看来,月份、日期和周之间确实是 “或” 的关系

 

关于共享库的学习笔记

关于共享库的学习可以参看: 《程序员的自我修养》

1. 为什么需要SONAME?

Linux中提供了一个工具叫做“ldconfig”,当系统中安装或更新一个共享库时,就需要运行这个工具,它会遍历所有的默认共享目录,比如/lib、/usr/lib等,然后更新所有的软连接,是他们指向最新版的共享库; 如果安装了新的共享库,那么ldconfig会为其创建相应的软连接。如果新版本的共享库文件被意外删除了,则软连接将自动更新到较低版本的共享库文件。

但是,如果你的共享库没有指定SONAME ,则ldconfig将无法自动更新软连接。

2. 如何查看共享库的SONAME

如图:

3. 不是所有的共享库都(必须)有SONAME,如何指定SONAME呢?

注意:使用 -Wl,-soname,your_soname 指定 你的SONAME

4. 使用了ldconfig后,编译新的程序还是找不到共享库(-lphpor),为什么?

ldconfig 只是为我们创建了满足程序运行的软连接,没有创建供程序编译使用的软连接;需要手动创建软连接:

程序编译之后,就和该软连接没有关系了,程序将只依赖指定的SONAME了

5. 相关命令的演示

6. 可以使用静态库生成共享库,不能使用共享库来编译出静态链接文件

gcc的 -static 的使用:(下面有些乱七八糟了,还没明白怎么回事儿)

7. 如何生成一个静态链接的共享库?

8.如何使用共享库生成一个静态链接文件?

 

关于PHP5.4的closure

参考: http://us.php.net/manual/en/closure.bind.php

有如下测试:

上述代码说明: 通过Closure的bind方法是可以访问一个对象的private属性的;这个是不是有悖于程序设计原则?

当mongodb超过最大连接数

要解决的问题

使用PHP 的mongo模块连接mongodb时,可能会出现打开的文件描述符未关闭的情况,直到文件描述符的数量达到limit的限制而出错。

 

启动mongod,设置最大连接数为5(方便调试):

消费连接数:

测试脚本mongo.php:

测试:

 

发现错误信息(结果却还是没有出现文件描述符未关闭的情况):

19:max number of retries exhausted, couldn’t send query
4:couldn’t get response header