onload与DOMContentLoaded区别

  • onload: 当onload事件触发时候,页面上面所有的DOM、样式表、脚本、图片、flash都已经加载完成, 并且多个onload只会有一个被触发
  • DOMContentLoaded: 当DOMContentLoaded事件触发时候,仅仅当DOM加载完成,不包括样式表、图片、flash

实际使用到的场景

  1. 假如我们需要给元素绑定事件,但当页面元素还没有加载完成前,绑定事件函数及已经触发了,那是没有效果的;
  2. 或者,lazy image功能,当我们允许DOM加载完毕,但图片并没有完成加载的,这时需要默认放置一张图片或者其他效果

代码例子

  • 在使用Jquery情况下,你可以使用$(document).ready来代替DOMContentLoaded

  • 在JS情况下,你可以有两种方式来实现$(document).ready:

ready实现的代码:

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;
    
    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
    	// Use the handy event callback
    	document.addEventListener( "DOMContentLoaded", function(){
    	document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
    		jQuery.ready();
    	}, false );
    
    // If IE event model is used
    } else if ( document.attachEvent ) {
    	// ensure firing before onload,
    	// maybe late but safe also for iframes
    	document.attachEvent("onreadystatechange", function(){
    		if ( document.readyState === "complete" ) {
    		document.detachEvent( "onreadystatechange", arguments.callee );
    		jQuery.ready();
    	}
    });
    	// If IE and not an iframe
    	// continually check to see if the document is ready
    if ( document.documentElement.doScroll && window == window.top ) (function(){
    	if ( jQuery.isReady ) return;
    
    	try {
    		// If IE is used, use the trick by Diego Perini
    		// http://javascript.nwbox.com/IEContentLoaded/
    		document.documentElement.doScroll("left");
    	} catch( error ) {
    		setTimeout( arguments.callee, 0 );
    		return;
    	}
    
    	// and execute any waiting functions
    	jQuery.ready();
    	})();
    	}
    
    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

为你的方法添加DOMContentLoaded事件:

document.addEventListener('DOMContentLoaded',function(){/*fun code to run*/})

Syntax highlighting is a feature that displays source code, in different colors and fonts according to the category of terms. This feature facilitates writing in a structured language such as a programming language or a markup language as both structures and syntax errors are visually distinct. Highlighting does not affect the meaning of the text itself; it is intended only for human readers.1

Pygments Code Blocks

To modify styling and highlight colors edit

1
/_sass/_pygments.scss
.

#container {
    float: left;
    margin: 0 -240px 0 0;
    width: 100%;
}
<nav class="pagination" role="navigation">
    {% if page.previous %}
        <a href="{{ site.url }}{{ page.previous.url }}" class="btn" title="{{ page.previous.title }}">Previous article</a>
    {% endif %}
    {% if page.next %}
        <a href="{{ site.url }}{{ page.next.url }}" class="btn" title="{{ page.next.title }}">Next article</a>
    {% endif %}
</nav><!-- /.pagination -->
module Jekyll
  class TagIndex < Page
    def initialize(site, base, dir, tag)
      @site = site
      @base = base
      @dir = dir
      @name = 'index.html'
      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
      self.data['tag'] = tag
      tag_title_prefix = site.config['tag_title_prefix'] || 'Tagged: '
      tag_title_suffix = site.config['tag_title_suffix'] || '&#8211;'
      self.data['title'] = "#{tag_title_prefix}#{tag}"
      self.data['description'] = "An archive of posts tagged #{tag}."
    end
  end
end

Standard Code Block

1
2
3
4
5
6
7
8
<nav class="pagination" role="navigation">
    {% if page.previous %}
        <a href="{{ site.url }}{{ page.previous.url }}" class="btn" title="{{ page.previous.title }}">Previous article</a>
    {% endif %}
    {% if page.next %}
        <a href="{{ site.url }}{{ page.next.url }}" class="btn" title="{{ page.next.title }}">Next article</a>
    {% endif %}
</nav><!-- /.pagination -->

Fenced Code Blocks

To modify styling and highlight colors edit

1
/_sass/_coderay.scss
. Line numbers and a few other things can be modified in
1
_config.yml
. Consult Jekyll’s documentation for more information.

1
2
3
4
5
#container {
    float: left;
    margin: 0 -240px 0 0;
    width: 100%;
}
1
2
3
4
5
6
7
8
<nav class="pagination" role="navigation">
    {% if page.previous %}
        <a href="{{ site.url }}{{ page.previous.url }}" class="btn" title="{{ page.previous.title }}">Previous article</a>
    {% endif %}
    {% if page.next %}
        <a href="{{ site.url }}{{ page.next.url }}" class="btn" title="{{ page.next.title }}">Next article</a>
    {% endif %}
</nav><!-- /.pagination -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module Jekyll
  class TagIndex < Page
    def initialize(site, base, dir, tag)
      @site = site
      @base = base
      @dir = dir
      @name = 'index.html'
      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
      self.data['tag'] = tag
      tag_title_prefix = site.config['tag_title_prefix'] || 'Tagged: '
      tag_title_suffix = site.config['tag_title_suffix'] || '&#8211;'
      self.data['title'] = "#{tag_title_prefix}#{tag}"
      self.data['description'] = "An archive of posts tagged #{tag}."
    end
  end
end

GitHub Gist Embed

An example of a Gist embed below.

Sample Link Post

This theme supports link posts, made famous by John Gruber. To use, just add

1
link: http://url-you-want-linked
to the post’s YAML front matter and you’re done.

##Crontab

###介绍:

crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。该词来源于希腊语 chronos(χρόνος),原意是时间。

通常,crontab储存的指令被守护进程激活, crond常常在后台运行,每一分钟检查是否有预定的作业需要执行。这类作业一般称为cron jobs。

我们Rails里面一个gem whenever用的就是crontab功能

###How to

crontab文件包含送交cron守护进程的一系列作业和指令。每个用户可以拥有自己的crontab文件;同时,操作系统保存一个针对整个系统的crontab文件,该文件通常存放于/etc或者/etc之下的子目录中,而这个文件只能由系统管理员来修改。

例如ubuntu /etc/crontab就是对于整个系统crobtab文件

View Crontab help:

1
crontab -h

Edit Your Crontab:

1
crontab -e

View Users Cronjob:

1
crontab -u userName -l

View Root User Cronjob:

1
crontab -l

View /etc/crontab:

A cronjob can be also run from /etc/crontab file. To view it, enter:

1
less /etc/crontab

View Daily Cronjob:

Type the following commands:

1
2
3
cd /etc/cron.daily/
ls -l
cat filename

View Hourly Cronjobs:

Type the following commands:

1
2
3
4
cd /etc/cron.hourly/
ls -l
cat filename
View Weekly Cronjobs

View Weekly Cronjobs:

Type the following commands:

1
2
3
4
cd /etc/cron.weekly/
ls -l
cat filename
View Monthly Cronjobs

View Monthly Cronjobs:

Type the following commands:

1
2
3
cd /etc/cron.monthly/
ls -l
cat filename

View Software (Package) Specific Cronjobs:

Type the following commands:

1
2
3
cd /etc/cron.d/
ls -l
cat filename

###操作符号

在一个区域里填写多个数值的方法

1
2
3
4
5
- 逗号,分开的值,例如 1,3,4,7,8
- 连词符-制定值的范围,例如 1-6,意思等同于1,2,3,4,5,6
- 星号*代表任何可能的值。例如,在“小时域” 里的星号等于是“每一个小时”,等等

某些cron程序的扩展版本也支持斜线 ('/') 操作符,用于表示跳过某些给定的数。例如,“*/3”在小时域中等于“0,3,6,9,12,15,18,21”等被3整除的数;

###时间设置

1
2
3
4
5
6
7
8
# 文件格式说明
#  ——分钟 (0 - 59)
# |  ——小时 (0 - 23)
# | |  ——日   (1 - 31)
# | | |  ——月   (1 - 12)
# | | | |  ——星期 (0 - 7)(星期日=0或7)
# | | | | |
# * * * * * 被执行的命令

注: 在“星期域”(第五个域),0和7都被视为星期日。 不很直观的用法:如果日期和星期同时被设定,那么其中的一个条件被满足时,指令便会被执行。请参考下例。 前5个域称之分时日月周,可方便个人记忆。 从第六个域起,指明要执行的命令。

###Example

1
2
3
4
5
6
7
8
9
10
11
 #===========================================================
 #      SYSTEM ACTIVITY REPORTS
 #  8am-5pm activity reports every 20 mins during weekdays.
 #  activity reports every hour on Saturday and Sunday.
 #  6pm-7am activity reports every hour during weekdays.
 #  summary prepared at 18:05 every weekday.
 #===========================================================
 0,20,40 8-17 * * 1-5 /usr/lib/sa/sa1 1200 3 &
 0 * * * 0,6 /usr/lib/sa/sa1 &
 0 18-7 * * 1-5 /usr/lib/sa/sa1 &
 5 18 * * 1-5 /usr/lib/sa/sa2 -s 8:00 -e 18:01 -i 3600 -ubcwyaqvm &

###实际使用

上面介绍完crontab一些知识以及怎样使用,接下去就来一个比较具体例子,在我们的app里面,当然会涉及到数据库备份,而且往往是放在凌晨来备份,好吧,那我们就定在凌晨一点整时间来备份数据库

首先,我们写一个数据库导出的bash脚本:

1
2
touch backup_mysql.sh
vim backup_mysql.sh

在backup_mysql.sh里面填入以下内容:

1
2
3
4
#!/bin/bash

backup="/#{path}/dump_`date +%d-%m-%Y`.sql"
/usr/bin/mysqldump -u#{user} -p#{user_password} databse_name | gzip > $backup.gz

接下去,我们就可以使用crontab job来帮我们定时1点执行:

注意!backup_mysql.sh必须是要有可执行权限哦

打开crontab编辑:

1
crontab -e

然后选择你需要编辑模式,定时执行backup_mysql.sh:

1
0 1 * * * /bin/bash -l -c 'bash /#{path}/backup_mysql.sh'

好了,接下去你就可以1点整时看看是否有备份;当然其他命令都是这样来使用crontab。如果觉得自己手动写crontab太过麻烦,觉得时间那些都比较难写,用Rails的童鞋们,建议使用下面这个gem whenever

https://github.com/javan/whenever

Cron Wiki:

http://zh.wikipedia.org/wiki/Cron

MySQL 开启与关闭远程访问

(1)通过MySQL用户去限制访问

权限系统目的:

MySQL基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root的远程访问权限,今天介绍的就是如何开启和关闭Mysql远程访问

MySQL权限系统的主要功能是证实连接到一台给定主机的用户,并且赋予该用户在数据库上的SELECT、INSERT、UPDATE和DELETE权限。 附加的功能包括有匿名的用户并对于MySQL特定的功能例如LOAD DATA INFILE进行授权及管理操作的能力。

权限系统原理:

MySQL权限系统保证所有的用户只执行允许做的事情。当你连接MySQL服务器时,你的身份由你从那儿连接的主机和你指定的用户名来决定。连接后发出请求后,系统根据你的身份和你想做什么来授予权限。

MySQL在认定身份中考虑你的主机名和用户名字,是因为几乎没有原因假定一个给定的用户在因特网上属于同一个人。例如,从office.com连接的用户joe不一定和从elsewhere.com连接的joe是同一个人。MySQL通过允许你区分在不同的主机上碰巧有同样名字的用户来处理它:你可以对joe从office.com进行的连接授与一个权限集,而为joe从elsewhere.com的连接授予一个不同的权限集。

阶段1:服务器检查是否允许你连接。 阶段2:假定你能连接,服务器检查你发出的每个请求。看你是否有足够的权限实施它。例如,如果你从数据库表中选择(select)行或从数据库删除表,服务器确定你对表有SELECT权限或对数据库有DROP权限。 如果连接时你的权限被更改了(通过你和其它人),这些更改不一定立即对你发出的下一个语句生效。MySQL权限是保存在cache中,这个时候就你需要执行

1
flush privileges;

开启远程访问:

  • 更新用户

    use mysql;

    update user set host = “%” where user = “root”;

    flush privileges;

  • 添加用户

    use mysql;

    insert into user(host, user, password) values(“%”, “root”, password(“yourpassword”))

    grant all privileges on . to ‘root’@’%’ with grant option #赋予任何主机访问数据库权限

    flush privileges;

关闭远程访问:

1
2
3
4
5
use mysql;

update user set host = "localhost" where user = "root" and host= "%";

flush privileges;

查看用户权限:

1
2
3
use information_schema;

select * from user_privileges;

查看当前mysql用户:

1
2
3
use mysql;

select user, host from user;

更新用户:

1
2
3
update mysql.user set password=password('新密码') where User="phplamp" and Host="localhost";

flush privileges;

删除用户:

1
2
3
DELETE FROM user WHERE User="phplamp" and Host="localhost";

flush privileges;

user host指定方法:

  • Host值可以是主机名或IP号,或’localhost’指出本地主机。
  • 你可以在Host列值使用通配符字符“%”和“_”。
  • host值’%’匹配任何主机名,空Host值等价于’%’。它们的含义与LIKE操作符的模式匹配操作相同。例如,’%’的Host值与所有主机名匹配,而’%.mysql.com’匹配mysql.com域的所有主机。

ip地址例子:

1
2
3
4
192.0.0.0/255.0.0.0(192 A类网络的任何地址)
192.168.0.0/255.255.0.0(192.168 A类网络的任何地址)
192.168.1.0/255.255.255.0(192.168.1 C类网络的任何地址)
192.168.1.1(只有该IP)

mysql doc:

http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html

(2)通过IpTable

iptables是一款防火墙软件。它在Ubuntu系统中是默认安装的。通常情况下,iptables随系统一起被安装,但没有对通信作任何限制,因此防火墙并没有真正建立起来。

iptables帮助:

1
sudo iptables -h #下面全部使用root用户调用指令

查看iptables:

1
2
3
4
5
6
7
8
9
10
iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

可以看到,上面规则都是空的

允许已建立的连接接收数据:

1
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

开放指定的端口:

接下来,我们可以尝试开放 ssh 22端口,告诉iptables允许接受到所有目标端口为22的tcp报文通过

1
iptables -A INPUT -p tcp -i eth0 --dport ssh -j ACCEPT

执行上面的命令,一条规则会被追加到INPUT规则表的末尾(-A表示追加)。根据这条规则,对所有从接口eth0(-i指出对通过哪个接口的报文运用此规则)接收到的目标端口为22的报文,iptables要执行ACCEPT行动(-j指明当报文与规则相匹配时应采取的行动)。

开放80端口:

1
iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT

这时,你再次去看看规则表中内容,你会发现有

1
2
3
4
5
6
7
iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www

通过上述命令,我们已经代开了SSH和web服务的相应的端口,但由于没有阻断任何通信,因此所有的报文都能通过,所以接下来,我们就可以尝试阻断3306 mysql端口

阻断通讯:

1
iptables -A INPUT  -p tcp -i eth0 --dport 3306 -j DROP

通过这样指令,就可以阻断任何访问3306报文,但是这样就有一个问题,就是可能连我们自己信任的主机都无法访问mysql了,所以,我们需要编辑下iptables,添加特定允许访问的主机

1
iptables -I INPUT 4 -p tcp -s ip_address -i eth0 --dport 3306 -j ACCEPT

好了,通过上面,我们把该指令插入到规则表里第四行,然后允许特定ip访问3306端口

Logging记录:

如果希望被丢失的报文记录到syslog中,最简单的方法可以这样做:

1
iptables -I INPUT 5 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

保存设置:

机器重启后,iptables中的配置信息会被清空。您可以将这些配置保存下来,让iptables在启动时自动加载,省得每次都得重新输入。iptables-save和iptables-restore 是用来保存和恢复设置的。

先将防火墙规则保存到/etc/iptables.up.rules文件中

1
iptables-save > /etc/iptables.up.rules

然后修改脚本/etc/network/interfaces,使系统能自动应用这些规则(最后一行是我们手工添加的)。

1
2
3
auto eth0
iface eth0 inet dhcp
pre-up iptables-restore < /etc/iptables.up.rules

当网络接口关闭后,您可以让iptables使用一套不同的规则集。

1
2
3
4
auto eth0
iface eth0 inet dhcp
pre-up iptables-restore < /etc/iptables.up.rules
post-down iptables-restore < /etc/iptables.down.rules

技巧(Tips):

大多数人并不需要经常改变他们的防火墙规则,因此只要根据前面的介绍,建立起防火墙规则就可以了。但是如果您要经常修改防火墙规则,以使其更加完善,那么您可能希望系统在每次重启前将防火墙的设置保存下来。为此您可以在/etc/network/interfaces文件中添加一行:

1
2
pre-up iptables-restore < /etc/iptables.up.rules
post-down iptables-save > /etc/iptables.up.rules