刚被哥's Blog

Ruby,Rails,Linux,Javascript,Nodejs and so on...

jQuery插件:模仿新浪轻博客添加标签效果

新浪轻博客发布文章时候,有个添加标签的效果非常不错,用户体验很棒。 由于工作需要,自己也试着写了一个jQuery插件,实现的效果如下面这样:

接下来介绍下如何使用这个插件:

1, 引入jQuery和tags.css文件

2, 在相关位置放一个div

1
<div class="ggTagContainer"></div>

class必须是ggTagContainer

3, 调用

1
2
3
4
5
6
jQuery(".ggTagContainer").tags({
   field: "tags1",                //field为保存tags的input(hidden)的name
   fieldId: "tags1",              //field为保存tags的input(hidden)的id
   tags: ["北京","上海","南京"],    //tags为热门标签
   has: ["美丽","幸福"]            //has为已经存在的标签
});

4, 最后您可以通过jQuery.mTags获取添加的标签,或者通过jQuery(“#tags1”)获取

5, Github托管地址:https://github.com/weekface/tags. 欢迎交流.

Nodejs两种使用EventEmitter的方法

Nodejs最吸引人的特性就是其事件驱动. 我们也可以使用nodejs提供的EventEmitter来写一些基于事件驱动的程序,有两种方法来实现: 1, 比较普通的,基于继承实现的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var events = require('events'),
sys = require('sys');

//定义Demo类
var Demo = function(){
    //Demo继承EventEmitter
    events.EventEmitter.call(this);

    this.p = function(){
        for(var i=0;i < 100; i++){
            if(i == 50){
                this.emit("data",i);
            }
        }
    }
};

//Demo继承EventEmitter
sys.inherits(Demo, events.EventEmitter);

//下面我们就来测试一旦找到50就停止打印.
//new一个Demo对象
var demo = new Demo();

//在demo对象emit ‘data’的时候,打印出50
demo.on('data', function(i){
    console.log(i);
});

//触发
demo.p();

2, 利用EventEmitter本身实现的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var events = require('events'),
sys = require('sys');

//定义Demo类
var Demo = function(){
    //new一个EventEmitter对象,并将其赋值给this.emitter
    var emitter = new events.EventEmitter();
    this.emitter = emitter;
};

Demo.prototype.p = function(){
    for(var i=0;i < 100; i++){
        if(i == 50){
            this.emitter.emit("data",i);
        }
    }
};

//下面我们就来测试一旦找到50就停止打印.
//new一个Demo对象
var demo = new Demo();

//在demo对象的emitter, emit ‘data’的时候,打印出50
demo.emitter.on('data', function(i){
    console.log(i);
});

//触发
demo.p();

在Github上托管的项目,两种方式使用的都挺多. JUST HAPPY!

非常不错的Nodejs工具:http-console

http-console是一个用nodejs写的类似于CURL的第三方库文件. 可以很直观的发送http请求以及查看返回结果. 安装需求: 1, 安装nodejs 2, 安装npm 3, npm install http-console 我做了个简单的例子: 启动: http-console 127.0.0.1:3000 1, HTTP GET:

1
2
3
4
5
6
7
8
9
10
11
12
13
http://127.0.0.1:3000/> GET /home

HTTP/1.1 200 OK
Etag: "5c7fa0cae55818cafc847a65e4bcb794"
Connection: close
Content-Type: application/json; charset=utf-8
Date: Mon, 17 Jan 2011 01:33:40 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-01-10)
X-Runtime: 13
Content-Length: 36
Cache-Control: private, max-age=0, must-revalidate

{ status: 'OK'}

2, HTTP POST:

1
2
3
4
5
6
7
8
9
10
11
12
13
http://127.0.0.1:3000/> POST /login
... username=weekface&password=1234
HTTP/1.1 200 OK
Etag: "5c7fa0cae55818cafc847a65e4bcb794"
Connection: close
Content-Type: application/json; charset=utf-8
Date: Mon, 17 Jan 2011 01:33:40 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-01-10)
X-Runtime: 13
Content-Length: 36
Cache-Control: private, max-age=0, must-revalidate

{ status: 'OK', username: "weekface"}

3, 还可以轻松的设置Headers, 保存cookies, 使用SSL等等. 比如如果我这样启动http-console: http-console 127.0.0.1:3000 –cookies 这样就会保存服务器端设置的cookies

1
2
3
4
5
6
7
http://127.0.0.1:3000/> \cookies
{
    _rails_session: {
        value: 'BAh7BzoQX2NzcmZfdG9rZW4iMWkvL0p1ZXAwUXVmWDNqdWJFVVNzT0k1akVwVEV1UDVWai9VZHFoekNSczA9Og9zZXNzaW9uX2lkIiVmMmU0N2M4NjMxZGZhNTQ0NGY2OTlhNmUwYzI2YjA1Nw==--70afef3fcc39b5109f1474d0c9a7935d8affc29c',
        options: { path: '/', HttpOnly: undefined }
    }
}

总而言之,http-console提供了CURL之外的另外一个不错的选择.也充分体现了nodejs的灵活与强大.

Install XEN to Centos

1,

1
[root@localhost ~]# yum install xen kernel-xen

2,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost ~]# vim /etc/grub.conf

default=0 #change 1 to 0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-238.12.1.el5xen)
        root (hd0,0)
        kernel /xen.gz-2.6.18-238.12.1.el5
        module /vmlinuz-2.6.18-238.12.1.el5xen ro root=LABEL=/ rhgb quiet
        module /initrd-2.6.18-238.12.1.el5xen.img
title CentOS (2.6.18-194.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-194.el5 ro root=LABEL=/ rhgb quiet
        initrd /initrd-2.6.18-194.el5.img

3,Close selinux and iptables

1
2
3
iptables -F
iptables -X
iptables -Z

4, mount centos iso

1
[root@localhost ~]# mount -o loop /home/weekface/CentOS-5.5-i386-bin-DVD.iso /home/weekface/data/iso

5, start nfs

1
2
3
4
5
[root@localhost ~]# vim /etc/exports
/home/weekface/data/iso *(ro)

[root@localhost ~]# service portmap start
[root@localhost ~]# service nfs start

6, install

1
2
3
virt-install -n vm01 -f /home/weekface/data/vm01.img -s 10 -r 512 nographics -l nfs:192.168.241.129:/home/weekface/data/iso

#virsh undefine vm01

7, 关闭domain0的iptables

1
2
3
4
5
6
7
vim /etc/xen/xend-conf.sxp
(network-script network-nat)
(vif-script vif-nat)

vim /etc/xen/vm01
vif = [ 'mac=00:16:3e:38:75:47, ip=10.0.0.101' ]
dhcp="off"

8,在domainU中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/etc/sysconfig/network-scripts/ifcfg-eth0
# Xen Virtual Ethernet
DEVICE=eth0
HWADDR=00:16:3e:38:75:47
ONBOOT=yes
NETMASK=255.255.255.0
IPADDR=10.0.0.101
GATEWAY=10.0.0.254
TYPE=Ethernet

vim /etc/resolv.conf
nameserver 211.91.88.129

vim /etc/sysconfig/network
HOSTNAME=vm01

/etc/init.d/network restart

做LVS实验之前,最好将Directer和RealServer的iptables全部关掉。

RAID5+LVM

具体做法是将三个硬盘组成raid5,在此之上建立VG和LV,将/root目录移动到新的逻辑卷上面并动态扩展其大小。最后增加一块新硬盘扩容。 1, 先给vmware增加三块硬盘,每个大小2G,并格式化后的设备分别为:

1
2
3
  /dev/sdb1
  /dev/sdc1
  /dev/sdd1

2,建立raid 5:

1
  [root@vm03 ~]# mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sdb1 /dev/sdc1 /dev/sdd1

3,建立raid 配置文件:

1
2
  [root@vm03 ~]# echo DEVICE /dev/sdb1 /dev/sdc1 /dev/sdd1
  [root@vm03 ~]# mdadm --detail --scan >> /etc/mdadm.conf

4,运行vgscan,会自动产生lvm的配置文件和目录

1
2
3
  [root@vm03 ~]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "VolGroup00" using metadata type lvm2

5,创建LVM物理卷

1
2
  [root@vm03 ~]# pvcreate /dev/md0
    Physical volume "/dev/md0" successfully created

6,创建卷组

1
2
  [root@vm03 ~]# vgcreate vg /dev/md0
    Volume group "vg" successfully created

7,检查下卷组的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  [root@vm03 ~]# vgdisplay vg
  --- Volume group ---
  VG Name               vg
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               4.00 GB
  PE Size               4.00 MB
  Total PE              1023
  Alloc PE / Size       0 / 0
  Free  PE / Size       1023 / 4.00 GB
  VG UUID               56b0zb-ZExF-zTCO-khQy-pe8B-KZPr-3usX9l

8,为home目录创建一个逻辑卷,并格式化

1
2
3
4
5
6
7
  [root@vm03 ~]# lvcreate -n home -l 250 vg     #其中 -l 250 指的是250个块,每块大小是4M,那么总共大小为1G
  Logical volume "home" created

  [root@vm03 ~]# mkfs.ext3 /dev/vg/home
  [root@vm03 ~]# mkdir /mnt/home
  [root@vm03 ~]# mount /dev/vg/home /mnt/home      #挂载到临时的mnt下,把文件拷贝过来
  [root@vm03 ~]# cp -a /root/* /mnt/home/

9,编辑/etc/fstab,在最后增加一行:

1
2
  [root@vm03 ~]# vim /etc/fstab       #真正挂载
  /dev/vg/home            /root                   ext3    defaults        0 0

10,reboot计算机 11,查看df

1
2
3
4
5
6
7
  [root@vm03 ~]# df
文件系统               1K-块        已用     可用 已用% 挂载点
/dev/mapper/VolGroup00-LogVol00
                       9014656   1370740   7178612  17% /
/dev/sda1               101086     12240     83627  13% /boot
tmpfs                   257652         0    257652   0% /dev/shm
/dev/mapper/vg-home    1007896     20944    935752   3% /root

12,将原来根目录挂载到临时目录/mnt下,并删除/root下面的所有文件,腾出空间

1
2
3
  [root@vm03 ~]# mount /dev/mapper/VolGroup00-LogVol00 /mnt
  [root@vm03 ~]# rm -rf /mnt/root/*
  [root@vm03 ~]# umount /mnt

13,扩展/root目录的大小,再增加一个G

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  [root@vm03 ~]# umount /root
  [root@vm03 ~]# e2fsck /dev/vg/home
    e2fsck 1.39 (29-May-2006)
    /dev/vg/home: clean, 276/128000 files, 9262/256000 blocks

  [root@vm03 ~]# lvextend -L +1000M /dev/vg/home
  Extending logical volume home to 1.95 GB
  Logical volume home successfully resized

  [root@vm03 ~]# e2fsck -f /dev/vg/home
  e2fsck 1.39 (29-May-2006)
  Pass 1: Checking inodes, blocks, and sizes
  Pass 2: Checking directory structure
  Pass 3: Checking directory connectivity
  Pass 4: Checking reference counts
  Pass 5: Checking group summary information
  /dev/vg/home: 276/128000 files (0.4% non-contiguous), 9262/256000 blocks

  [root@vm03 ~]# resize2fs /dev/vg/home
  resize2fs 1.39 (29-May-2006)
  Resizing the filesystem on /dev/vg/home to 512000 (4k) blocks.
  The filesystem on /dev/vg/home is now 512000 blocks long.

  [root@vm03 ~]# lvdisplay /dev/vg/home
  --- Logical volume ---
  LV Name                /dev/vg/home
  VG Name                vg
  LV UUID                FGEWY2-b3BQ-Y1PA-1rPb-kELE-FcJJ-QNmyqB
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                1.95 GB        #变成了1.95G大小了
  Current LE             500
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     512
  Block device           253:2

14,重新挂载/root

1
2
3
4
5
6
7
8
  [root@vm03 ~]# mount /dev/vg/home /root
  [root@vm03 ~]# df -h
  文件系统              容量  已用 可用 已用% 挂载点
  /dev/mapper/VolGroup00-LogVol00
                      8.6G  1.4G  6.9G  16% /
  /dev/sda1              99M   12M   82M  13% /boot
  tmpfs                 252M     0  252M   0% /dev/shm
  /dev/mapper/vg-home   2.0G   21M  1.9G   2% /root

15,接下来给RAID5增加一块硬盘并扩充VG容量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[root@vm03 ~]# mdadm /dev/md0 -a /dev/sde1
mdadm: added /dev/sde1
[root@vm03 ~]# mdadm -G --raid-devices=4 /dev/md0
mdadm: Need to backup 384K of critical section..
mdadm: ... critical section passed.

[root@vm03 ~]# mv /etc/mdadm.conf /etc/mdadm.conf.bak
[root@vm03 ~]# echo DEVICE /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
DEVICE /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
[root@vm03 ~]# mdadm --detail --scan >> /etc/mdadm.conf

[root@vm03 ~]# pvresize /dev/md0
Physical volume "/dev/md0" changed
1 physical volume(s) resized / 0 physical volume(s) not resized

-bash-3.2# vgdisplay vg
  --- Volume group ---
  VG Name               vg
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  4
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               6.00 GB             #可以看到VG空间增加到了6G
  PE Size               4.00 MB
  Total PE              1535
  Alloc PE / Size       500 / 1.95 GB
  Free  PE / Size       1035 / 4.04 GB
  VG UUID               56b0zb-ZExF-zTCO-khQy-pe8B-KZPr-3usX9l

其实还可以将操作系统的/目录移动到LVM设备上面,比较复杂,在这里就不做演示了。

RHEL4.8 Install Oracle

首先选择Oracle安装的操作系统是:RHEL4.8.这是Oracle文档上列出的适合安装的系统。貌似centos不可以。 安装RHEL4.8时候所要选择的安装包有: X Window System, GNOME Desktop enveroment, Editors, Development tools, Legacy Software Development. 下面为安装步骤: 1, 创建用户、配置所需环境变量:新建1preuser.sh键入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
echo "Now create two groups named 'oinstall' and 'dba', plus a user named 'oracle'.Also setting the Environment"
groupadd oinstall
groupadd -g 502 dba
groupadd -g 503 oper
groupadd -g 504 asmadmin
groupadd -g 505 oinstall
useradd -g oinstall -G dba,oper,asmadmin,oinstall -c "Oracle software owner" -d /home/oracle oracle
echo "oracle"   passwd --stdin oracle
echo "export ORACLE_BASE=/u01/app" >> /home/oracle/.bash_profile
echo 'export ORACLE_HOME=$ORACLE_BASE/oracle' >> /home/oracle/.bash_profile
echo "export ORACLE_SID=orcl" >> /home/oracle/.bash_profile
echo 'export LD_LIBRARY_PATH=$ORACLE_HOME/lib' >> /home/oracle/.bash_profile
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib:/usr/X11R6/lib' >> /home/oracle/.bash_profile
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/jdk/jre/lib/i386' >> /home/oracle/.bash_profile
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/jdk/jre/lib/i386/server' >> /home/oracle/.bash_profile
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/rdbms/lib' >> /home/oracle/.bash_profile
echo 'export CLASS_PATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib' >> /home/oracle/.bash_profile
echo 'export CLASS_PATH=$CLASS_PATH:$ORACLE_HOME/rdbms/jlib' >> /home/oracle/.bash_profile
echo 'export CLASS_PATH=$CLASS_PATH:$ORACLE_HOME/network/jlib' >> /home/oracle/.bash_profile
echo 'export TNS_ADMIN=$ORACLE_HOME/network/admin' >> /home/oracle/.bash_profile
echo "export NLS_LANG=american_america.AL32UTF8" >> /home/oracle/.bash_profile
echo "export ORACLE_TERM=xterm" >> /home/oracle/.bash_profile
echo "export EDITOR=vi" >> /home/oracle/.bash_profile
echo 'export PATH=$ORACLE_HOME/bin:$PATH' >> /home/oracle/.bash_profile
echo "export LANG=en_US" >> /home/oracle/.bash_profile
echo "export LANG=en_US" >> /home/oracle/.bash_profile
echo "The two groups named 'oinstall' and 'dba' plus the oracle user has been created."
echo "The Environment variable for oracle user also has been setted sussessfully."

2, 创建目录—–2predir.sh

1
2
3
4
5
echo "Now create the necessary directory for oracle user and change the authention to oracle user..."
mkdir -p /u01/app/oracle
chown -R oracle:oinstall /u01
chown oracle:oinstall /home/oracle
echo "The necessary directory for oracle user and change the authention to oracle user has been finished

3.解除安装oracle所有者的shell—3prelimits.sh

1
2
3
4
5
6
7
echo "Now modify the /etc/security/limits.conf,but backup it named /etc/security/limits.conf.bak before"
cp    /etc/security/limits.conf    /etc/security/limits.conf.bak
echo "oracle soft nproc 2047" >>/etc/security/limits.conf
echo "oracle hard nproc 16384" >>/etc/security/limits.conf
echo "oracle soft nofile 1024" >>/etc/security/limits.conf
echo "oracle hard nofile 65536" >>/etc/security/limits.conf
echo "Modifing the /etc/security/limits.conf has been succeed."

4.修改登录文件—4prelogin.sh

1
2
3
4
5
echo "Now modify the /etc/pam.d/login,but with a backup named /etc/pam.d/login.bak"
cp /etc/pam.d/login    /etc/pam.d/login.bak
echo "session required /lib/security/pam_limits.so" >>/etc/pam.d/login
echo "session required pam_limits.so" >>/etc/pam.d/login
echo "Modifing the /etc/pam.d/login has been succeed."

5.修改环境变量—5bpreprofile.sh

1
2
3
4
5
6
7
8
9
10
11
echo "Now modify the /etc/profile,but with a backup named /etc/profile.bak"
cp /etc/profile /etc/profile.bak
echo 'if [ $USER = "oracle" ]; then' >> /etc/profile
echo 'if [ $SHELL = "/bin/ksh" ]; then' >> /etc/profile
echo 'ulimit -p 16384' >> /etc/profile
echo 'ulimit -n 65536' >> /etc/profile
echo 'else' >> /etc/profile
echo 'ulimit -u 16384 -n 65536' >> /etc/profile
echo 'fi' >> /etc/profile
echo 'fi' >> /etc/profile
echo "Modifing the /etc/profile has been succeed."

6.修改内核参数—6.presysctl.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
echo "Now modify the /etc/sysctl.conf,but with a backup named /etc/sysctl.bak"
cp /etc/sysctl.conf /etc/sysctl.conf.bak
echo "fs.file-max = 65536" >> /etc/sysctl.conf
echo "kernel.sem = 250 32000 100 128" >> /etc/sysctl.conf
echo "kernel.shmall = 2097152" >> /etc/sysctl.conf
echo "kernel.shmmni = 4096" >> /etc/sysctl.conf
echo "kernel.shmmax = 2147483648" >> /etc/sysctl.conf
echo "net.core.rmem_default=1048576" >> /etc/sysctl.conf
echo "net.core.rmem_max=262144" >> /etc/sysctl.conf
echo "net.core.wmem_default=262144" >> /etc/sysctl.conf
echo "net.core.wmem_max=262144" >> /etc/sysctl.conf
echo "net.ipv4.ip_local_port_range = 1024 65000" >> /etc/sysctl.conf
echo "Modifing the /etc/sysctl.conf has been succeed."
echo "Now make the changes take effect....."
sysctl -p

将这些脚本文件chown u+x *.sh 并依次执行。

下载10201_database_linux32.zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
unzip 10201_database_linux32.zip

[root@localhost ~]# mv database/ /u01/
[root@localhost u01]# chown -R oracle:oinstall database/
[oracle@database]$ ./runInstaller #必须是oracle用户并且是startx进入xwindow界面
[oracle@oracle ~]$ dbca  #创建数据库

[oracle@oracle ~]$ sqlplus /nolog

SQL*Plus: Release 10.2.0.1.0 - Production on Sun Jul 17 19:58:55 2011

Copyright (c) 1982, 2005, Oracle.  All rights reserved.
SQL> conn / as sysdba
Connected.

设置Oracle

1
2
[oracle@oracle ~]$ vim .bash_profile
stty erase ^?  #可以使用backspace消除字符

安装rlwrap-0.30.tar.gz

1
2
[oracle@oracle ~]$ vim .bash_profile
alias sqlplus='rlwrap sqlplus /nolog'  #可以使用方向键上下调节命令

ERROR 1045 (28000): Access Denied for User ‘Root’@’localhost’ (Using Password: YSE)

莫名其妙的错误,解决办法是修改root密码. 首先把所有mysql的进程杀掉. 然后:

安全启动mysql

1
# mysqld_safe --user=mysql --skip-grant-tables --skip-networking &

进入mysql

1
# mysql -u root mysql

更新root密码

1
2
3
mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root';
mysql> FLUSH PRIVILEGES;
mysql> quit

最后重新启动mysql就可以了

1
# /etc/init.d/mysql start

Javascript中this的使用

JavaScript 中的 this 一直是让我迷惑的部分,本文内容基本来自于 这篇文章

在一个 function 的执行过程中,如果变量的前面加上了 this 作为前缀的话,如this.myVal,对此变量的求值就从 this 所表示的对象开始.

this 的值取决于 function 被调用的方式,一共有四种,具体如下:

1, 如果一个 function 是一个对象的属性,该 funtion 被调用的时候,this 的值是这个对象。如果 function 调用的表达式包含句点(.)或是 [],this 的值是句点(.)或是 [] 之前的对象.举个例子:

1
2
3
4
5
6
7
var some = {
    name: "zhangsan",
    speak: function(){ //此时function是some对象的一个属性(speak)
        return this.name; //此时的this就是只some对象
    }
}
console.log(some.speak()); //输出"zhangsam"

2, 如果一个 function 不是作为一个对象的属性,那么该 function 被调用的时候,this 的值是全局对象.当一个 function 中包含内部 function 的时候,如果不理解 this 的正确含义,很容易造成错误.这是由于内部 function 的 this 值与它外部的 function 的 this 值是不一样的。在下面的例子中,在myObj的func中有个内部名为inner的 function,在inner被调用的时候,this 的值是全局对象,因此找不到名为myVal的变量.这个时候通常的解决办法是将外部 function 的 this 值保存在一个变量中(此处为self),在内部 function 中使用它来查找变量.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var myObj = {
  myVal : "Hello World",
  func : function() {
     console.log(typeof this.myVal);    // 结果为 string
     console.log(this.myVal);    // 结果为 "Hello World"
     var self = this;
     function inner() {
       console.log(typeof this.myVal);  // 结果为 undefined
       console.log(typeof self.myVal);  // 结果为 string
       console.log(self.myVal);  // 结果为 "Hello World"
     }
     inner();
  }
 };

myObj.func();

3, 如果在一个 function 之前使用 new 的话,会创建一个新的对象,该 funtion 也会被调用,而 this 的值是新创建的那个对象.举个例子:

1
2
3
4
5
6
function User(name) {
    this.name = name
};
var user1 = new User("Alex");

console.log(user1.name); //输出 "Alex"

在上面的例子中,通过调用new User(“Alex”),会创建一个新的对象,以user1来引用,User这个 function 也会被调用,会在user1这个对象中设置名为name的属性,其值是Alex.

4, 可以通过 function 的 apply 和 call 方法来指定它被调用的时候的 this 的值. apply 和 call 的第一个参数都是要指定的 this 的值,两者不同的是调用的实际参数在 apply 中是以数组的形式作为第二个参数传入的,而 call 中除了第一个参数之外的其它参数都是调用的实际参数.举个例子:

1
2
func.apply(anotherObj, [arg1, arg2]) //func调用时候的 this 指的是anotherObj,两个参数分别是arg1和arg2
func.call(anotherObj, arg1, arg2) //同上

Over!

Nodejs结合javascript的闭包的一个例子

Nodejs结合javascript的闭包的一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//server.js文件
var http = require('http');
var dispatcher = require('./dispatcher.js'); //dispatcher模块

//在这里我们就可以利用闭包,将一些环境变量设置下来,dispatcher.perform方法必须返回一个匿名function
var perform = dispatcher.perform({
    "hello": "world"
});

http.createServer(function(request, response) {
    //处理请求,perform必须为一个function,并且需要两个参数(request, response)
    perform(request, response);
}).listen(80);


//******************华丽的分割线*******************


//dispatcher.js文件
//定义perform,利用闭包的特性绑定了vars变量
exports.perform = function(vars) {
    return function(request, response) {
        response.end(JSON.stringify(vars));
    }
}

Vsftpd虚拟用户设置

本文原作者:dbzhang800,本人稍作修改

首先我们假定你已经安装了vsftpd,并在/var/ftp目录下建立了以下2个子目录: widget, server 下面,我们要建2个虚拟用户,密码分别是用户名后加”00”:

1
2
widget,server
widget00, server00

使得: 用户widget 的主目录为/var/ftp/widget ,在该目录下只有只读许可权 用户server 的主目录为/var/ftp/server ,在该目录下拥有所有许可权 创建文本文件loguser.txt, 格式如下:

1
2
user_id
password

于是,我们/home/loguser.txt文件的内容为

1
2
3
4
widget
widget00
server
server00

生成资料库

我们执行下面的命令:

1
db_load -T -t hash -f /home/logins.txt /etc/vsftpd_login.db

最后设置一下资料库文件的访问许可权

1
sudo chmod 600 /etc/vsftpd_login.db

配置PAM文件

新建/etc/pam.d/vsftpd.vu 内容如下:

1
2
auth required /lib/security/pam_userdb.so db=/etc/vsftpd_login
account required /lib/security/pam_userdb.so db=/etc/vsftpd_login

我们上一步建立的资料库vsftpd_login 在此处被使用 我们建立的虚拟用户将采用PAM进行验证,这是通过/etc/vsftpd/vsftpd.conf文件中的语句pam_service_name=vsftpd.vu来启用的,稍后你将发现。 为虚拟用户创建本地系统用户

新建一个系统用户virtual,用户家目录为/var/ftp, 用户登录终端设为/bin/false(即使之不能登录系统)

1
2
sudo useradd virtual -d /var/ftp -s /bin/false
sudo chown virtual:virtual /var/ftp

编辑: /etc/vsftpd/vsftpd.conf 一般要确保含有以下设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
listen=YES
anonymous_enable=NO
dirmessage_enable=YES
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
chroot_local_user=YES
guest_enable=YES
guest_username=virtual
user_config_dir=/etc/vsftpd/vsftpd_user_conf
pam_service_name=vsftpd.vu
local_enable=YES
#secure_chroot_dir=/var/run/vsftpd 本人将其注视掉了,否则报错

现在为止,我们的2个用户都可以工作了,可是它们的根目录现在都是/var/ftp,许可权也都一样。那么怎么才能完成我们预定的目标呢?

在上面的配置中,有这么一行:

1
user_config_dir=/etc/vsftpd/vsftpd_user_conf

现在,我们要把各个用户的配置文件放到目录/etc/vsftpd/vsftpd_user_conf中

1
2
3
mkdir /etc/vsftpd/vsftpd_user_conf
cd /etc/vsftpd/vsftpd_user_conf
touch widget server

widget文件中的内容如下

1
local_root=/var/ftp/widget #只读

server文件中的内容:

1
2
3
4
5
6
write_enable=YES
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
local_root=/var/ftp/server

这里要注意不能有空格,不然登录的时候会提示出错。我的这里面也有问题,

重启vsftpd我们就可以看到效果了_^

1
/etc/init.d/vsftpd start|restart

如果遇到任何有关目录权限的问题就将SELinux关闭,或者干脆:

1
yum remove selinux* -y