动态script标签加载js文件需要注意的问题

对于下面一段js代码

<?php
var excuteScript = function (id, scriptSource, charset
) {
var
head = document.getElementsByTagName(‘head’)[0
];
var
oldScript = document.getElementById(id
);
if (
oldScript
) {
head.removeChild(oldScript
);
}
var
newScript = document.createElement(‘script’
);
if (
charset
) {
newScript.charset = charset
;
} else {
newScript.charset = ‘gb2312’
;
}
newScript.id = id
;
newScript.type = ‘text/javascript’
;
scriptSource += (/?/.test(scriptSource)?"&":"?") + "_=" + (new Date()).getTime
();
newScript.src = scriptSource
;
head.appendChild(newScript
);
};
?>

对于IE和firefox是有所不同的:
IE: 请求发起在给script标签的src属性赋值的时候,至少ie8是这样
Firefox: 请求发起于appendChild的时候,如果创建的标签没有append操作,将不会发起请求; 至少firefox 3.0.11 是这样

我们可以通过下面的脚本测试一下:

<html>
<
head><title>test script </title></head>
<
body>
<
script>
scriptSource = "http://phpor.net/404.js";
var
head = document.getElementsByTagName(‘head’)[0];
var
oldScript = document.getElementById(id);
if (
oldScript) {
head.removeChild(oldScript);
}
var
newScript = document.createElement(‘script’);
newScript.charset = ‘gb2312’;
newScript.id = "testid";
newScript.type = ‘text/javascript’;

newScript.src = scriptSource;
newScript.src = scriptSource +"?2";
//head.appendChild(newScript);

</script>
</body>
</html>

http://phpor.net/samples/html/test_script.html

陈奎家住陕西延安城

歌手名:曲剧
歌曲名:陈奎家住陕西延安城
专辑名:陈三两

陈奎家住陕西延安城,南门以里有他的门庭。
他是个独生子,七岁把书攻,不幸遭大火,家财被烧清;
可怜他的二爹娘,火坑丧性命,单撇下陈奎自己孤苦伶仃。
无奈何武定州去投亲朋,只可惜世态炎凉无人照应。
走投无有路,流落大街中,挨门去讨饭,谁能把他疼。
偶遇衙前班头,收他去打更。打一更钱一个,二更二文铜。
那一日正半夜,大祸从天生。衙门失了盗,窃贼无影踪,拿住了小陈奎下绝情。
这才是屋漏偏遇连阴雨,行船遇着顶头风。打更钱一文不能要,苦苦逼他招口供。
打得他死去活来险些丧命,衙内不要他再不能打更。
小陈奎万般无计奈,又只得左提棍右挎篮挨门挨户沿街讨要去操旧营生。
那一日陈奎讨饭去到富春院,我见他衣褴褛面憔悴真是可怜。
我将他唤上北楼问一遍,俺们二人身世苦都似黄连。
我赠他纹银二十两,周济他糊口把衣添。
小陈奎得银两不买衣饭,到大街买诗文只把书观。
我见他人穷志不短,就有心周济他奇儿男。

读起书来了——
我陈奎操碎我一片心肠,老鸨儿打得我周身是伤。
苦口又婆心,教他读文章,我与他又订下提铃计一桩。
大街上买来了铜铃绒线,从北楼扯到了西楼上边。陈奎在西楼把书念,我在北楼把文观。
夜半内听不到书音贯耳,就知那小陈奎昏昏入眠。
在北楼扯动红绒线,响铜铃惊醒陈奎又把书观。
日月如梭光阴似箭,西楼上读书有好几年。我教会他文章有三百篇,梅花篆字我亲手传。
北京城里开科选,陈奎进京去求官。
伸手拉住小兄弟,有几句金石良言你牢记在心间。
得中要把清官做,且莫要草菅人命做贪官。
得中后搭救姐姐出离苦海,再与我屈死二老报仇冤。
这几件大事要牢牢记下,也不枉我苦口婆心教读你几年。


陈奎好比一只虎,陈三两好比捕鼠猫。猛虎跟着猫学艺,胆大狸猫把虎教。
窜山跳涧都教会,得第把我恩忘了。大老爷你替我想一想,这样的门徒可教不可教。
我好比一只孤舟在顺水漂,船到江心失了篙。有前因无后果,有了上枝无下梢。
指河南我把陈奎骂,你的文章是谁教。得恩不报非君子,忘恩负义小儿曹。
陈三两越骂我心越恼……

apache异常分析全过程

关于apache中的异常:

现象:
1、 10.49.4.61 的httpd访问不了,但是访问却又不是立即退出,而是一直等待
2、 10.49.4.61 的httpd子进程240个,不再变化
3、 netstat 发现很多close_wait 的连接; 就是客户端已经断开,但是服务器还没有断开的情况 

分析:
1. tcpdump 发现连接已建立,也发送了一些请求数据,接着就什么也没有了; 说明请求并没有被apache子进程给接走
2. netstat 查看一下,发现Recv-Q 里面确实有数据
3. strace httpd子进程发现每个子进程都如下:
 write(11, "10.49.4.21 – – [12/Jul/2009:10:2"…, 101 <unfinished …>

 显然,要写apache日志,而且是今天10点20多时的日志,但是被某种原因给阻塞了,下面就是要知道为什么阻塞了
4. 看一下fd = 11 是个什么东西:
 [root@sso115 htdocs]# ll /proc/17151/fd/
 total 0
 lr-x—— 1 root root 64 Jul 12 10:53 0 -> /dev/null
 l-wx—— 1 root root 64 Jul 12 10:53 1 -> /dev/null
 lr-x—— 1 root root 64 Jul 12 10:53 10 -> eventpoll:[41846266]
 l-wx—— 1 root root 64 Jul 12 10:53 11 -> pipe:[41551707]
 lrwx—— 1 root root 64 Jul 12 10:53 12 -> socket:[41846267]
 l-wx—— 1 root root 64 Jul 12 10:53 13 -> pipe:[41551708]
 l-wx—— 1 root root 64 Jul 12 10:53 2 -> /data1/apache2/logs/error_log
 lrwx—— 1 root root 64 Jul 12 10:53 3 -> socket:[39585452]
 lrwx—— 1 root root 64 Jul 12 10:53 4 -> socket:[39585453]
 lr-x—— 1 root root 64 Jul 12 10:53 5 -> pipe:[41551704]
 l-wx—— 1 root root 64 Jul 12 10:53 6 -> pipe:[41551704]
 l-wx—— 1 root root 64 Jul 12 10:53 7 -> /data1/apache2/logs/access_log
 l-wx—— 1 root root 64 Jul 12 10:53 8 -> pipe:[41551705]
 l-wx—— 1 root root 64 Jul 12 10:53 9 -> pipe:[41551706]

 原来是个管道,可能是管道写满了;那么这个管道是做什么的呢?

5. 应该是和rotatelogs程序共有的pipe,验证如下:
 rotatelogs 只剩下三个进程了,应该有四个呢,肯定被谁误杀了一个!!!
 [root@sso115 ~]# ps aux | grep rot                    
 root     29709  0.0  0.0  61116   736 pts/1    S+   14:04   0:00 grep rot
 root     31469  0.0  0.0  23524   696 ?        S    Jul10   0:00 /data1/apache2/bin/rotatelogs /data1/apache2/logs/%Y%m/online.internal.sina.com.cn-80-error_log.%Y%m%d 86400 480
 root     31470  0.0  0.0  23524   692 ?        S    Jul10   0:00 /data1/apache2/bin/rotatelogs /data1/apache2/logs/%Y%m/online.sso.sina.com.cn-80-error_log.%Y%m%d 86400 480
 root     31472  0.0  0.0  23524   692 ?        S    Jul10   0:00 /data1/apache2/bin/rotatelogs /data1/apache2/logs/%Y%m/online.sso.sina.com.cn-80-access_log.%Y%m%d 86400 480
 [root@sso115 ~]#
 
 每个进程里面都没有这个管道
 [root@sso115 ~]# ll /proc/31469/fd
 total 0
 lr-x—— 1 root root 64 Jul 12 10:53 0 -> pipe:[41551705]
 l-wx—— 1 root root 64 Jul 12 10:53 1 -> /dev/null
 l-wx—— 1 root root 64 Jul 12 10:53 2 -> /data1/apache2/logs/error_log

 [root@sso115 ~]# ll /proc/31470/fd
 total 0
 lr-x—— 1 root root 64 Jul 12 10:53 0 -> pipe:[41551706]
 l-wx—— 1 root root 64 Jul 12 10:53 1 -> /dev/null
 l-wx—— 1 root root 64 Jul 12 10:53 2 -> /data1/apache2/logs/error_log
 [root@sso115 ~]#

 [root@sso115 ~]# ll /proc/31472/fd
 total 0
 lr-x—— 1 root root 64 Jul 12 10:53 0 -> pipe:[41551708]
 l-wx—— 1 root root 64 Jul 12 10:53 1 -> /dev/null
 l-wx—— 1 root root 64 Jul 12 10:53 2 -> /data1/apache2/logs/error_log
 [root@sso115 ~]#

 显然,那个rotatelogs进程肯定是被谁给杀掉了,或者是出现意外死亡了;
 查了一下系统log,有看了一下用户的.bash_history 都没有发现和rotatelogs相关的信息

6. 没法查下去了,不过可以做一个测试,就是把rotatelogs进程杀掉,是否就肯定出现这种现象
 使用graceful的办法重启apache,原以为不能凑效,因为请求都是为处理完的,而且不可能处理完的;但是还是都死掉了

7. 重启apache,两个虚拟机,四个rotatelogs 进程; 试图杀死一个rotatelogs进程,但总是立即又出现了一个新的,以为该进程具有自派生机制,
 就用 kill -9 来杀,结果还是立即重新启动一个;
 观察了一下新的进程的ppid,发现时apache守护进程的pid,于是用strace监视一下apache的守护进程; 因为rotatelogs 进程是apache守护
 进程的子进程,所以rotatelogs进程死掉的时候会给apache守护进程发送一个信号,apache守护进程就可以根据自己保存的管道在启动一个
 rotatelogs进程,于是这个进程就有了杀不死的功能了。
 可以用这个办法做杀不死进程。
 
 跟踪apache守护进程的主要信息
 22934 14:34:35.057195 wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGKILL}], WNOHANG|WSTOPPED, NULL) = 31358
 22934 14:34:35.057365 write(2, "piped log program \’/data1/apache"…, 154) = 154
 22934 14:34:35.057490 dup(10)           = 14
 22934 14:34:35.057561 dup(11)           = 15
 22934 14:34:35.057619 dup(1)            = 16
 22934 14:34:35.057689 dup(2)            = 17
 22934 14:34:35.057893 access("/data1/apache2/bin/rotatelogs", X_OK) = 0
 22934 14:34:35.057991 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2aaaab123c70) = 31463

应用程序如何立即知道网络的连接状态

当网络断开时,UC可以立即知道,MSN也能立即知道;

当网络重新已连接时,UC没有立即发现,MSN能立即发现。

为什么呢?MSN是如何立即知道网络状态的变化的呢?

 

google了一下,发现一篇相关的文章:http://www.flextheworld.com/2009/01/adobe-air-web-status.html/comment-page-1

它使用了每3s测试一次网络状态的办法,显然这没有实现“立即”,更可恨的是,它是用别人的网页(google的首页)来测试的;可能这人脑袋被驴踢过。

 

继续寻找答案,感觉是系统底层提供了这样的事件通知。

看一下这篇文章:http://blog.csdn.net/luozhenyu/archive/2009/04/27/4130223.aspx

是C#写的一个例子,基本原理是调用系统的API,当然是.net Framework 里的方法,检查网络连接的状态,至少这种检查是不需要真正连网的,所以循环检查是可以接受的。

 还有就是可以直接调用windows的API,可能是:InternetGetConnectedState函数

 

daemo 初始化代码

下面是memcached中初始化一个daemo的代码,如果我们自己要写daemo的话,这个可以参考:

1. fork时使用了switch结构,而不是if … else

2. 提供了一个参数,决定是否重定向标准输入、标准输出、标准错误

#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

int daemon(int nochdirint noclose)
{
    
int fd
;

    switch (fork()) {
    case –
1
:
        return (-
1
);
    case 
0
:
        break;
    default:
        
_exit(EXIT_SUCCESS
);
    }

    if (setsid() == –1)
        return (-
1
);

    if (nochdir == 0)
        (
void)chdir("/"
);

    if (noclose == && (fd open("/dev/null"O_RDWR0)) != –1) {
        (
void)dup2(fdSTDIN_FILENO
);
        (
void)dup2(fdSTDOUT_FILENO
);
        (
void)dup2(fdSTDERR_FILENO
);
        if (
fd STDERR_FILENO
)
            (
void)close(fd
);
    }
    return (
0
);
}

openssl rsa 使用简介

openssl命令的用法

 密钥的生成

 a. 生成非对称密钥对
openssl genrsa -out rsa.key
b. 指定生成的密钥的位数,默认512
openssl genrsa -out rsa_2048.key 2048
c. 为私钥添加密码 (一般都不用)
openssl genrsa -out rsa_des3.key -des3


密钥的查看

d. 查看私钥
openssl rsa -in rsa.key
e. 查看公钥
openssl rsa -in rsa.key -pubout
f. 查看公钥和modulus
openssl rsa -in rsa.key -modulus
g. 查看密钥的详细信息,包含component prime等细节信息,这些信息的值都是冒号分割的,称为abstract
openssl rsa -in rsa.key -text
h. 查看只有public key的文件
openssl rsa -in pub.txt -pubin
注:
pub.txt 可由
openssl rsa -in rsa.key -pubout >pub.txt

openssl rsa -in rsa.key -pubout -out pub.txt
产生
如果pub.txt 中不是公钥将报错, -pubin 仅仅说明 -in 所指定的文件里面是什么
i. 只查看key的其他信息,不显示key
openssl  rsa -in rsa.key -noout

openssl rsautl 系列

1. 使用生成的公钥加密文件

-in指定要加密的文件,-inkey指定密钥,-pubin表明是用纯公钥文件加密,-out为加密后的文件

2. 使用生成的私钥解密文件

-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件

参考: http://www.cnblogs.com/aLittleBitCool/archive/2011/09/22/2185418.html

 

其它:

检查是否含有某个子命令
openssl no-rsa
输出rsa,命令的返回值为1,说明存在该子命令
openssl no-des5
输出no-des5 命令的返回值为0,说明不存在des5这个子命令

分析key的详细信息
openssl asn1parse -in rsa.key
openssl asn1parse -in pub.txt

 

签名和签名的验证

  这里给出一个例子:

基本步骤:

1. 生成rsa密钥对

2. 用私钥做签名

3. 用公钥做验证

[root@bsso ~]# openssl
OpenSSL> genrsa -out rsa.1024 1024
Generating RSA private key, 1024 bit long modulus
………..++++++
……….++++++
e is 65537 (0x10001)
OpenSSL> rsa -in rsa.1024 -pubout
writing RSA key
—–BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0BlFXN1wkgBb5hadMeLz4Pqj2
nZQGyyidW1GTun9rnKkG7o/v/YM8MCcrqW+2hizkbJygfRGvb1iHvc22SD7Q1Unk
7yKU5qDiDnXdIl1x05PMGRwfNhG75uv9tr/IsxA+bmIrEAZ+fxlGhXbg8R2gUm2O
c51AyBOgb92DtEfLgQIDAQAB
—–END PUBLIC KEY—–
OpenSSL> rsa -in rsa.1024 -pubout -out rsa.1024.pub
writing RSA key
OpenSSL> dgst -sign rsa.1024 -sha1 -out a.sign a.php
OpenSSL> dgst -verify rsa.1024.pub -sha1 -signature a.sign a.php

Verified OK
OpenSSL>

 

如何查看公钥的位数:

解释一个错误的说法: 上面的公钥base64 decode 之后为94字节, 不能说该公钥的位数为 94*8 = 752位; 而是用上面的方法查看,为: 512位

 

浏览器与http referer的问题

关于referer,它有很多用途,但是,只有我们真正理解了其含义,才不至于错用,下面说几个referer需要注意的问题

1. 对于firefox,关于referer这部分是可以在about:config里面设置的

2. 一般来讲

         点击一个a标签,访问一个目标页面,这时referer是源页面

         在标签里面访问一个地址,如: img   script 标签的src属性,这时src地址的请求里可以得到referer

3. 跳转时一般没有referer

         使用location.href = "b.htm";则b.htm得不到referer

         使用location.replace("b.htm");则b.htm得不到referer

         使用header("Location: b.htm");则b.htm得不到referer

         怎么跳转可以得到referer呢?

         使用form表单的形式跳转,如:

       <html>
        <
head>
                <
title>redirect</title>
        </
head>
        <
body onload="document.getElementById(‘f’).submit()">
                <
form id="f" action="a.php" method="post">
                        <
input type="hidden" name="n" value="m" />
                </
form>
        </
body>
       </
html>

关于apache的跟踪

曾经修改过/etc/resolve.conf后,发现apache进程里还是使用旧的dns server来解析域名,重启apache后才生效;这里给出几个确认的办法:

办法一: 如果服务器上没有其它需要域名解析的进程的话,使用tcpdump 来观察53端口的udp包就基本可以知道了

                  命令: tcpdump -i eth1 -nn -X -s 0  "port 53 and udp"

办法二: 随便找一个httpd的子进程strace一下就基本知道了,但是要求两点:

                  1. 访问量比较大,随时都有做域名解析的可能;而且程序里确实有做域名解析的需要

                   2. httpd子进程不会死的太快,太快了你会抓不到的

                  命令: strace -p pid_of_httpd_child -e trace=network 2>&1 | grep "(53)"

办法三: 因为httpd子进程可能死的太快,我们就从httpd的守护进程着手
                 命令: strace -p pid_of_httpd_parent -fF -e trace=network 2>&1 | grep "(53)"