实时监听页面变化的Chrome Extenstion案例

工程名Chrome_Extenstion_Bider
适用于chrome内核的浏览器
目录结构

1
2
3
4
5
6
7
Chrome_Extenstion_Bider/Bider/css
|-Chrome_Extenstion_Bider/Bider/css/common.css
Chrome_Extenstion_Bider/Bider/include
|-Chrome_Extenstion_Bider/Bider/include/jquery-1.11.0.min.js
Chrome_Extenstion_Bider/Bider/scripts
|-Chrome_Extenstion_Bider/Bider/scripts/main.js
Chrome_Extenstion_Bider/Bider/manifest.json

Chrome_Extenstion_Bider/Bider/manifest.json

1
2
3
4
5
6
7
8
9
10
11
12
{
    "manifest_version": 2,
    "name": "Bider",
    "version": "0.1.0",
    "description": "Bider.",
    "content_scripts": [{
        "matches": ["http://www.hillmatrix.com/*"],
        "css": ["css/common.css"],
        "js": ["include/jquery-1.11.0.min.js", "scripts/main.js"],
        "all_frames": true
    }]
}

Chrome_Extenstion_Bider/Bider/css/common.css

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#ls_box {
    position: absolute;
    width: 500px;
    height: 300px;
    background-color: #fff;
    border-radius: 5px;
    border: 1px solid #ccc;
    left: 50%;
    top: 50%;
    margin-left: -250px;
    margin-top: -150px;
    z-index: 99999;
    padding: 10px;
}

#ls_box h3 {
    height: 30px;
    line-height: 30px;
    border-bottom: 1px solid #ccc;
    margin: 0 0 5px 0;
    padding: 0;
}

#ls_box #ls_panel {
    height: 105px;
    margin: 10px 0;
}

#ls_box #ls_panel #ls_ms {
    color: blue;
    display: inline-block;
}

#ls_box #ls_panel #ls_warn {
    color: red;
    width: 312px;
    text-align: right;
    display: inline-block;
}

#ls_box #ls_panel #ls_list {
    overflow-x: hidden;
    overflow-y: scroll;
    height: 90px;
    margin: 0;
    padding: 0;
}

#ls_box #ls_panel #ls_list ul li {
    height: 24px;
    line-height: 24px;
    border-bottom: 1px dotted #efefef;
}

#ls_box #ls_panel #ls_list ul li span {
    float: right;
    cursor: pointer;
}

#ls_box #ls_form {
    background-color: #efefef;
    border-radius: 5px;
    padding: 10px;
}

#ls_box #ls_form label {
    padding: 0 5px;
    display: inline-block;
}

#ls_box #ls_form #ls_panel {
    padding: 0 5px;
}

#ls_box #ls_form input {
    width: 120px;
    padding: 5px 10px;
    display: inline-block;
}

#ls_box #ls_form #ls_btnc {
    width: auto;
    padding: 5px 10px;
    text-align: center;
}

#ls_box #ls_form button {
    padding: 5px 10px;
    display: inline-block;
    margin-right: 20px;
}

Chrome_Extenstion_Bider/Bider/include/jquery-1.11.0.min.js

Chrome_Extenstion_Bider/Bider/scripts/main.js

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
var main = {
    flag: false,
    flash: 200,
    money: 0,
    // 初始化
    init: function(target) {
        // 创建界面
        this.create(target);

        // 获取页面数据
        this.listenPage();

        //绑定按钮
        this.bindBtn();
    },

    //绑定BTN
    bindBtn: function() {
        _this = this;

        var ls_start = $('#ls_start');
        var ls_stop = $('#ls_stop');
        var ls_max = $('#ls_max');
        var ls_step = $('#ls_step');

        if (!_this.flag) {
            ls_stop.attr("disabled", "disabled");
            ls_start.removeAttr("disabled");
            ls_max.removeAttr("disabled");
            ls_step.removeAttr("disabled");
        } else {
            ls_start.attr("disabled", "disabled");
            ls_stop.removeAttr("disabled");
            ls_max.attr("disabled", "disabled");
            ls_step.attr("disabled", "disabled");
        }

        ls_start.bind("click", function() {
            if (!_this.flag) {
                ls_start.attr("disabled", "disabled");
                ls_stop.removeAttr("disabled");
                ls_max.attr("disabled", "disabled");
                ls_step.attr("disabled", "disabled");
                _this.flag = true;
            }
        });

        ls_stop.bind("click", function() {
            if (_this.flag) {
                ls_stop.attr("disabled", "disabled");
                ls_start.removeAttr("disabled");
                ls_max.removeAttr("disabled");
                ls_step.removeAttr("disabled");
                _this.flag = false;
            }
        });
    },

    //动态竞标价
    activePrice: function() {
        _this = this;
        var page_sendbtn = $('#bidBtnId');
        var page_pi = $('.TB_priceInput');

        var ls_max = parseInt($('#ls_max').val());
        var ls_step = parseInt($('#ls_step').val());
        //console.log(_this.flag);
        if (_this.flag && ls_max > 0 && ls_step > 0) {
            var cmoney = parseInt(_this.money);
            var m1 = cmoney + ls_step;
            var m2 = ls_max + ls_step;
            if (m1 <= ls_max) {
                page_pi.val(m1);
                $('#ls_warn').html('当前出价:' + m1);
            } else if (cmoney == ls_max) {
                page_pi.val(m2);
                $('#ls_warn').html('当前出价(MAX+1):' + m2);
            } else {
                $('#ls_warn').html('已经超出最大限额+1步长,停止竞标');
                $('#ls_stop').delay(500).click();
            }
        } else if (!_this.flag) {
            $('#ls_warn').html('自动竞标系统停止中');
        } else {
            $('#ls_warn').html('请设置正确的参数');
        }
    },

    // 创建界面
    create: function(target) {
        var _html = '<div id="ls_box">' + '<h3>' + 'Bider' + '</h3>' + '<div id="ls_panel">' + '<div>毫秒计数器:<span id="ls_ms">0</span><span id="ls_warn"></span></div>' + '<ul id="ls_list">正在加载数据...' + '</ul>' + '</div>' + '<div id="ls_form">' + '<div id="ls_panel">' + '<h3>' + '策略' + '</h3>' + '<label>' + '最高价: ' + '</label>' + '<input type="text" id="ls_max" value="0" />' + '<label>' + '步长: ' + '</label>' + '<input type="text" id="ls_step" value="10" />' + '<br />' + '<div id="ls_btnc"><button id="ls_start">开始</button><button id="ls_stop">停止</button></div>' + '</div>' + '</div>' + '</div>';
        target.closest("body").append(_html);
    },

    /**
     * 监听页面数据变化
     */

    listenPage: function() {
        _this = this;
        var page_countDown = $('#countDown_counting'); //the element I want to monitor

        page_countDown.bind('DOMCharacterDataModified DOMSubtreeModified', function(e) {
            var page_cp = $('#currentPrice').html();
            var price_arr = page_cp.split("/");
            var page_cp_total = price_arr[0];
            var page_cp_single = price_arr[1];
            _this.money = page_cp_single;

            var dataList = ['当前状态:总价:' + page_cp_total + ',单价:' + page_cp_single];
            dataList.push('倒计时:' + $('#countDown_counting').html() + '秒');
            _this.printData(dataList);
        });
    },

    /**
     * 将已有数据写到页面上
     */

    printData: function(dataList) {
        if (!dataList || dataList.length == 0) {
            $("#ls_list").html('<p>获取数据失败</p>');
            return;
        }
        // 遍历对象,构建输出html
        var _html = [];
        for (var i in dataList) {
            _html.push('<li>' + dataList[i] + '</li>');
        }
        $("#ls_list").html(_html.join(''));
    },
}

var ext_c = $('#countDown_counting');
//console.log(ext_c[0]);
if (ext_c[0] != undefined) {
    main.init(ext_c);
    var ext_t = parseInt(ext_c.html()) * 1000;
    var ext_isclick = false;
    ext_c.bind('DOMCharacterDataModified DOMSubtreeModified', function(e) {
        if ($.isNumeric($(this).html())) {
            ext_t = parseInt($(this).html()) * 1000;
        }
    });

    var ext_ms = function() {
            var ext_s = 0;
            if (ext_t > 0) {
                ext_t -= 17;
                ext_s = ext_t;
            }
            if (ext_c.html() == '0') {
                ext_c.unbind();
                clearInterval(ext_run);
            }
            console.log(ext_s);
            $('#ls_ms').html(ext_s);
            if (ext_s <= main.flash && !ext_isclick && main.flag) {
                ext_isclick = true;
                console.log('倒计时剩余:' + ext_s + '毫秒,提交请求!');
                ext_c.unbind();
                clearInterval(ext_run);
                $('#bidBtnId').click();
            }
            main.activePrice();
        }

        //毫秒级计数器
    var ext_run = setInterval(ext_ms, 15);
}

Chrome_Extenstion_Bider

JS原生方法监听DOM结构改变事件

https://developer.mozilla.org/en-US/docs/XUL/Events#Mutation_DOM_events

1
2
3
document.addEventListener('DOMNodeInserted',function(){alert(1)},false);
document.addEventListener('DOMAttrModified',function(){alert(1)},false);
document.addEventListener('DOMNodeRemoved',function(){alert(1)},false);

变动事件包括以下不同事件类型:

1
2
3
4
5
6
7
DOMSubtreeModified; //在DOM结构中发生任何变化时触发
DOMNodeInserted; //在一个节点作为子节点被插入到另一个节点中时触发
DOMNodeRemoved; //在节点从其父节点中被移除时触发
DOMNodeRemovedFromDocument; //在一个节点被直接从文档中移除或通过子树间接从文档中移除之前触发
DOMNodeInsertedIntoDocument; //在一个节点被直接插入文档或通过子树间接插入文档之后触发
DOMAttrModified; //在属性被修改之后触发
DOMCharacterDataModified; //在文本节点的值发生变化时触发

SSH反向隧道链接及Autossh守护进程的使用

1.建立SSH反向隧道链接:

A要控制B

A主机:外网,ip:123.123.123.123,sshd端口:2221
B主机:内网,sshd端口:2223

无论是外网主机A,还是内网主机B都需要跑ssh daemon

1.1.首先在B上执行

1
$ ssh -NfR 1234:localhost:2223 user1@123.123.123.123 -p2221

这句话的意思是将A主机的1234端口和B主机的2223端口绑定,相当于远程端口映射(Remote Port Forwarding)。

这里每次需要输入A主机user1的登陆密码,后面会讲到解决办法。

1.2.这时在A主机上sshd会listen本地1234端口

1
2
3
$ ss -ant
State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port
LISTEN     0      128               127.0.0.1:1234                     *:*

1.3.像平时一样连接到A主机的1234端口就可以控制内网B主机了

1
$ ssh localhost -p1234

2.这种反向连接(Reverse Connection)不稳定,可能随时断开,需要内网主机B再次向外网A发起连接,将自动连接ssh的应用Autossh制作成daemon,每次开机自动运行,并且可以使用service进行开关控制。

在此之前还要解决之前的一个问题,那就是每次内网主机B连接外网主机A时都需要输入密码,这个问题ssh本身是提供另外一种验证方式——通过密钥验证用户身份,实现自动登录。

2.1.在内网B主机上生产公钥和私钥

1
2
3
4
$ ssh-keygen
...(一直按Enter,最后在~/.ssh/下生成密钥)
$ ls ~/.ssh/
id_rsa id_rsa.pub known_hosts

2.2.复制B主机上生成的id_rsa.pub公钥到外网A主机上,并将内容加入到~/.ssh/authorized_keys

ssh-copy-id命令添加到远程主机的自动验证

1
$ ssh-copy-id user1@123.123.123.123

2.3.制作Autossh的daemon

使用vim编辑,如果没有则新建

SysV:/etc/inid.d/autossh

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/bin/bash  
### BEGIN INIT INFO  
#  
# Provides:  location_server  
# Required-Start:   $local_fs  $remote_fs  
# Required-Stop:    $local_fs  $remote_fs  
# Default-Start:    2 3 4 5  
# Default-Stop:     0 1 6  
# Short-Description:    initscript  
# Description:  This file should be used to construct scripts to be placed in /etc/init.d.  
#  
### END INIT INFO  
 
## Fill in name of program here.  
PROG=&quot;autossh&quot;  
PROG_PATH=&quot;/usr/bin&quot; ## Not need, but sometimes helpful (if $PROG resides in /opt for example).  
PROG_ARGS=&quot;-M 5678 -NR *:2222:127.0.0.1:8080 root@123.123.123.123 -p 22&quot;  
PID_PATH=&quot;/var/run/&quot;  
 
start() {  
    if [ -e &quot;$PID_PATH/$PROG.pid&quot; ]; then  
        ## Program is running, exit with error.  
        echo &quot;Error! $PROG is currently running!&quot; 1&amp;gt;&amp;amp;2  
        exit 1  
    else  
        ## Change from /dev/null to something like /var/log/$PROG if you want to save output.  
        $PROG_PATH/$PROG $PROG_ARGS 2&amp;gt;&amp;amp;1 &amp;gt;/var/log/$PROG &amp;amp;  
    $pid=`ps ax | grep -i 'location_server' | sed 's/^[0−9]{1,}.*/\1/g' | head -n 1`  
 
        echo &quot;$PROG started&quot;  
        echo $pid &amp;gt; &quot;$PID_PATH/$PROG.pid&quot;  
    fi  
}  
 
stop() {  
    echo &quot;begin stop&quot;  
    if [ -e &quot;$PID_PATH/$PROG.pid&quot; ]; then  
        ## Program is running, so stop it  
    pid=`ps ax | grep -i 'location_server' | sed 's/^[0−9]{1,}.*/\1/g' | head -n 1`  
    kill $pid  
         
        rm -f  &quot;$PID_PATH/$PROG.pid&quot;  
        echo &quot;$PROG stopped&quot;  
    else  
        ## Program is not running, exit with error.  
        echo &quot;Error! $PROG not started!&quot; 1&amp;gt;&amp;amp;2  
        exit 1  
    fi  
}  
 
## Check to see if we are running as root first.  
## Found at http://www.cyberciti.biz/tips/bash-root-user-check-script.html  
if [ &quot;$(id -u)&quot; != &quot;0&quot; ]; then  
    echo &quot;This script must be run as root&quot; 1&amp;gt;&amp;amp;2  
    exit 1  
fi  
 
case &quot;$1&quot; in  
    start)  
        start  
        exit 0  
    ;;  
    stop)  
        stop  
        exit 0  
    ;;  
    reload|restart|force-reload)  
        stop  
        start  
        exit 0  
    ;;  
    **)  
        echo &quot;Usage: $0 {start|stop|reload}&quot; 1&amp;gt;&amp;amp;2  
        exit 1  
    ;;  
esac

php多版本共存的配置(nginx+php5.2 & 5.5 & 5.6)

首先安装好不同版本的php

1
2
3
root@ubuntu:/usr/local# ls
autoconf-2.13 bin curl etc freetype games include lib man mysql nginx php php5.2 php5.6 sbin share src zend zend52
root@ubuntu:/usr/local#

配置
以防修改配置文件出错,可以先做好备份

1
vim etc/php-fpm.conf

需要注意下面几处配置

1
<value name="listen_address">127.0.0.1:9100</value>

这个表示php的fastcgi进程监听的ip地址以及端口。因为本地已经有一个5.6版本了所以这里改成9100 nobody

1
<value name="group">nobody</value>

表示php的fastcgi进程以什么用户以及用户组来运行,默认该行是注释掉的,需要打开

1
<value name="display_errors">0</value>

是否显示php错误信息

1
<value name="max_children">5</value>

最大的子进程数目
运行php-fpm: php-fpm用一个程序来控制fastcgi进程,这个文件在$PREFIX/sbin/php-fpm

php5.6版本的php-fpm.conf文件

成功运行php-fpm后
nginx配置

1
2
3
4
5
6
7
8
9
10
11
12
13
server{
    listen 80;
    server_name php5.2.com;
    index index.html index.htm index.php;
    root /home/wwwroot/php5.2;

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9100;      #这里把fastcgi_pass 改到本地的9100端口
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include fastcgi_params;
    }
}

启动

1
/usr/local/php5.2/sbin/php-fpm start

php5.3之后官方收录了php-fpm,所以之后的版本不用加start参数
再把启动命令写入/etc/rc.local文件中,开机启动。
到此实现以不同域名访问同一主机。

Ubuntu下搭建FTP服务器

在Linux中ftp服务器的全名叫 vsftpd,我们需要利用相关命令来开启安装ftp服务器,然后再在vsftpd.conf中进行相关配置,下面我来介绍在Ubuntu中vsftpd安装与配置增加用户的方法。

1.首先用命令检查是否安装了vsftpd

1
vsftpd -version

这里写图片描述
如果未安装用一下命令安装

1
sudo apt-get install vsftpd

安装完成后,再次输入vsftpd -version命令查看是否安装成功

2.新建一个文件夹用于FTP的工作目录

1
mkdir /home/ftp

这里写图片描述

3.新建FTP用户并设置密码以及工作目录
ftpname为你为该ftp创建的用户名

1
sudo useradd -d /home/ftp -s /bin/bash ftpname

这里写图片描述

为新建的用户设置密码

1
passwd ftpname

【注释:用cat etc/passwd可以查看当前系统用户】

4.用命令打开vsftpd.conf

1
vi vsftpd.conf

这里写图片描述
设置属性值

1
2
3
anonymous_enable=NO #禁止匿名访问
local_enable=YES
write_enable =YES

保存返回
5.启动vsftpd服务

1
service vsftpd start

让DedeCMS完美兼容PHP5.4 解决织梦后台空白问题

或者大家在用dede的时候会发现,程序装好后,登录后台却发现是一片空白的。但换其他机器又没问题。那是织梦默认的是不支持php5.4版本的。
无法正常登录,将下面代码粘贴到/include/helpers/util.helper.php中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fix for removed Session functions

function fix_session_register() {
    function session_register() {
        $args = func_get_args();
        foreach($args as $key) {
            $_SESSION[$key] = $GLOBALS[$key];
        }
    }

    function session_is_registered($key) {
        return isset($_SESSION[$key]);
    }

    function session_unregister($key) {
        unset($_SESSION[$key]);
    }
}
if (!function_exists('session_register')){
    fix_session_register();
}

Debian 6(Squeeze)升级至Debian 7(Wheezy)

Debian GNU/Linux支持滚动更新,出于安全方面的考虑,当新版Debian发行后,我们一般会将现有版本的Debian升级至最新的稳定版的Debian。升级除了可以提升系统的安全性以外,同时还可以获得由更新版本的应用软件带来的新功能及其它好处。这就是我们为什么要将Debian 6(Squeeze)升级至Debian 7(Wheezy)的原因。

1. 编辑/etc/apt/source.list文件

编辑/etc/apt/source.list文件,将文件中的squeeze全部换成wheezy即可,之后查看/etc/apt/source.list文件,其内容应大致如下:

1
2
3
4
5
6
7
8
9
10
cat /etc/apt/sources.list
deb http://ftp.us.debian.org/debian/ wheezy main
deb-src http://ftp.us.debian.org/debian/ wheezy main

deb http://security.debian.org/ wheezy/updates main
deb-src http://security.debian.org/ wheezy/updates main

wheezy-updates, previously known as 'volatile'
deb http://ftp.us.debian.org/debian/ wheezy-updates main
deb-src http://ftp.us.debian.org/debian/ wheezy-updates main

2.更新软件包列表

1
apt-get update

如果更新软件包列表时,提示:
W: There is no public key available for the following key IDs:
8B48AD6246925553
则需要导入Debian 7(Wheezy)的Archive Keys。

Debian Archive Signing Keys下载页面:http://ftp-master.debian.org/keys.html

1
2
wget http://ftp-master.debian.org/keys/archive-key-7.0.asc
apt-key add archive-key-7.0.asc

之后重新更新软件包列表就不会提示该警告了。

1
apt-get update

3.更新最小化的基本系统

1
apt-get upgrade

4.升级剩下的系统

1
apt-get dist-upgrade

5.重启系统

1
reboot

6.验证系统

1
2
lsb_release -a
cat /etc/debian_version

7.检查内核

1
uname -msr

8.删除不再需要的软件包

1
apt-get autoremove && apt-get autoclean

怎样实现织梦dede搜索结果页按频道模型显示不同模板

大家知道怎样实现dede搜索结果页按频道模型显示不同模板吗,这问题网上看到不少朋友都在问,究竟怎样才能实现呢,下面是笔者总结的些方法:
dedecms门户模板的时候经常会有图片模型、文章模型、软件模型之类的,要是给搜索框加一个判定,例如搜索软件模型的时候显示一个模板,搜索文章模型的时候显示一个模板。
具体实现代码:
1 在head区域加入

1
2
3
4
5
6
7
8
9
10
<script language="javascript" type="text/javascript">
<!--
 function check(){
  if(document.formsearch.channeltype.value=="3")
  document.formsearch.action="{dede:field name='phpurl'/}/search_images.php"
  else
  document.formsearch.action="{dede:field name='phpurl'/}/search.php"
 }
-->
</script>

2 更改搜索代码

1
2
3
4
5
6
7
8
9
10
11
<form  name="formsearch" action="" *****ubmit="check();">
    <div class="form">
        <input type="hidden" name="kwtype" value="0" />
        <input name="q" type="text" class="search-keyword" id="search-keyword" value="{dede:global name='keyword' function='RemoveXSS(@me)'/}" />
        <select name="channeltype" id="channeltype" >
            <option value='1' selected='1'>新闻</option>
            <option value='3'>软件</option>
        </select>
        <button type="submit" class="search-submit">搜索</button>
     </div>
</form>

其中重点就是

1
2
3
4
<select name="channeltype" id="channeltype" >
    <option value='1' selected='1'>新闻</option>
    <option value='3'>软件</option>
</select>

关键设置:这里设置的按游戏模型搜索 1是文章模型 3是软件模型

3 复制serach.php 更名为 search_images.php
4 打开 search_images.php

1
require_once(DEDEINC."/arc.searchview.class.php");

更改为

1
require_once(DEDEINC."/arc.searchimg.class.php");

5复制 arc.searchview.class.php 更名为 arc.searchimg.class.php

6 打开 arc.searchimg.class.php
修改

1
2
 $tempfile = $GLOBALS['cfg_basedir'].$GLOBALS['cfg_templets_dir']."/".$GLOBALS['cfg_df_style']."/search.htm";
 $tempfile = $GLOBALS['cfg_basedir'].$GLOBALS['cfg_templets_dir']."/".$GLOBALS['cfg_df_style']."/search_images.htm";

核心的修改已经结束了,剩下的就是在search_images.htm这个模板里自由发挥了。
同理也可以实现按栏目type搜索显示不同风格的结果页得。

Nginx配置文件try_files语法及在WP Super Cache中的应用

try_files 是nginx0.6.36 后新增一个功能,用于搜索指定目录下的N个文件,如果找不到fileN,则调用fallback中指定的位置来处理请求。个人认为,作为nginx核心的内容,可以部分替代烦琐的rewrite功能,笔者把它用在wp super cache的rewrite重写中,也取得了不错的效果。

try_files
语法: try_files file1 [file2 … filen] fallback
默认值: 无
作用域: location

这个指令的作用就是可接收多个路径作为参数,当前一个路径的资源无法找到,则自动查找下一个路径,如当请求的静态资源不存在,就将请求fallback指定位置到后台服务器上进行动态处理。
简单的例子:

1
2
3
4
5
6
7
8
location / {
    try_files index.html index.htm @fallback;
}

location @fallback {
    root /var/www/error;
    index index.html;
}
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
server {
    set $cache /wp-content/cache/supercache/$host;
        #wp-super-cache的路径
    listen 80;
    server_name _;
    location / {
        root /home/html/s0001/domains/$host;
        index index.php index.html;
                #直接调用gzip压缩后的html静态文件
        add_header Content-Type "text/html; charset=UTF-8";
        add_header Content-Encoding "gzip";
        try_files $cache/$uri/index.html.gz @proxy;
 
    }
    #所有静态文件都由nginx处理,并用gzip压缩输出
    location ~* \.(jpg|jpeg|png|gif|css|js|swf|mp3|avi|flv|xml|zip|rar)$ {
        expires 30d;
        gzip on;
        gzip_types  text/plain application/x-javascript text/css application/xml;
        root /home/html/s0001/domains/$host;
    }
    #找不到的文件都交给后端的apache处理了
    location @proxy {
        index  index.php index.htm index.html;
        root   /home/html/$user/domains/$host;
            proxy_pass   http://127.0.0.1:8080;
            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;
    }
}

Nginx常用的超时配置说明

1
client_header_timeout

语法 client_header_timeout time
默认值 60s
上下文 http server
说明 指定等待client发送一个请求头的超时时间(例如:GET / HTTP/1.1).仅当在一次read中,没有收到请求头,才会算成超时。如果在超时时间内,client没发送任何东西,nginx返回HTTP状态码408(“Request timed out”)

1
client_body_timeout

语法 client_body_timeout time
默认值 60s
上下文 http server location
说明 该指令设置请求体(request body)的读超时时间。仅当在一次readstep中,没有得到请求体,就会设为超时。超时后,nginx返回HTTP状态码408(“Request timed out”)

1
keepalive_timeout

语法 keepalive_timeout timeout [ header_timeout ]
默认值 75s
上下文 http server location
说明 第一个参数指定了与client的keep-alive连接超时时间。服务器将会在这个时间后关闭连接。可选的第二个参数指定了在响应头Keep-Alive: timeout=time中的time值。这个头能够让一些浏览器主动关闭连接,这样服务器就不必要去关闭连接了。没有这个参数,nginx不会发送Keep-Alive响应头(尽管并不是由这个头来决定连接是否“keep-alive”)
两个参数的值可并不相同
注意不同浏览器怎么处理“keep-alive”头
MSIE和Opera忽略掉”Keep-Alive: timeout=” header.
MSIE保持连接大约60-65秒,然后发送TCP RST
Opera永久保持长连接
Mozilla keeps the connection alive for N plus about 1-10 seconds.
Konqueror保持长连接N秒

1
lingering_timeout

语法 lingering_timeout time
默认值 5s
上下文 http server location
说明 lingering_close生效后,在关闭连接前,会检测是否有用户发送的数据到达服务器,如果超过lingering_timeout时间后还没有数据可读,就直接关闭连接;否则,必须在读取完连接缓冲区上的数据并丢弃掉后才会关闭连接。

1
resolver_timeout

语法 resolver_timeout time
默认值 30s
上下文 http server location
说明 该指令设置DNS解析超时时间

1
proxy_connect_timeout

语法 proxy_connect_timeout time
默认值 60s
上下文 http server location
说明 该指令设置与upstream server的连接超时时间,有必要记住,这个超时不能超过75秒。
这个不是等待后端返回页面的时间,那是由proxy_read_timeout声明的。如果你的upstream服务器起来了,但是hanging住了(例如,没有足够的线程处理请求,所以把你的请求放到请求池里稍后处理),那么这个声明是没有用的,由于与upstream服务器的连接已经建立了。

1
proxy_read_timeout

语法 proxy_read_timeout time
默认值 60s
上下文 http server location
说明 该指令设置与代理服务器的读超时时间。它决定了nginx会等待多长时间来获得请求的响应。这个时间不是获得整个response的时间,而是两次reading操作的时间。

1
proxy_send_timeout

语法 proxy_send_timeout time
默认值 60s
上下文 http server location
说明 这个指定设置了发送请求给upstream服务器的超时时间。超时设置不是为了整个发送期间,而是在两次write操作期间。如果超时后,upstream没有收到新的数据,nginx会关闭连接

1
proxy_upstream_fail_timeout(fail_timeout)

语法 server address [fail_timeout=30s]
默认值 10s
上下文 upstream
说明 Upstream模块下 server指令的参数,设置了某一个upstream后端失败了指定次数(max_fails)后,该后端不可操作的时间,默认为10秒