强制使用小写的 url 地址

强制 使用小写的 url,这对于SEO避免重复内容惩罚尤其重要。在基于 windows 的服务器上更应该如此,因为 windows 默认情况下不区分大小写。对于良好的架构SEO来说,大小写混合的 url 重定向到标准化小写的 url 是非常有必要的

阅读更多

配置 HTTPS

重定向所有的站点到 https

通过在 nginx.conf 文件中添加以下内容,将所有非安全(HTTP)请求重定向到使用 HTTPS 连接的服务器上配置的任何站点

阅读更多

主域 - 添加或者移除 www

你的网站可能有多个域名访问,比如:www.wulicode.comwulicode.com 等,设置主域意思是不管用户输入哪个域名,都会 301 重定向到主域上,设置主域可以对 SEO 更友好,比如:

阅读更多

Nginx 状态码配置和错误文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
# 配置访问 /test.js 时报 403 错
location /test.js {
return 403;
}
# 配置访问 /404 时报 404 错
location /404 {
return 404;
}
# 配置访问 /500 时报 500 错
location /500 {
return 500;
}
# 把指定状态码指向这个文件 uri
error_page 500 502 503 504 /status.html;
error_page 404 /status.html;
}
<!-- more -->

如:

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 {
listen 80;
server_name test.me;
root /Users/xiaowu/work/test.me;
# 用if匹配任何以 403 开头的,会匹配到 /4034444
if ($request_uri ~* ^/403) {
return 403;
}
# 用location匹配 /500/ /500,但不匹配 /500/1
location ~* "^/500/?$" {
return 500;
}
# 用if匹配以 /501/ 开头的,匹配 /501/1,/501/1/2 但不匹配 /501
if ($request_uri ~* ^/501/) {
return 501;
}
# 用location匹配 /502/ /502 /502/1 /502/1/2
location ~* "^/502(/.*)?$" {
return 502;
}
# 用location只匹配 /503
location = /503 {
return 503;
}
}

error_page配置小提示

注意 error_page 配置时加 = 和不加 = 的区别,加了 = 表示响应为指定的 http status code ,默认为 200,不加 = 为原错误的状态码~

1
2
3
4
5
6
7
8
9
# 这样可以访问错误页面时 http status 为 404 ,并且页面内容是 404.html 的内容
error_page 404 /404.html
error_page 404 500 /404.html;
# 这样配置访问错误页面时 http status 为 200 ,但页面内容是 404.html 的内容
error_page 404 500 = /404.html;
# 这样配置访问错误页面时 http status 为 404 ,但页面内容是 404.html 的内容
error_page 404 500 =404 /404.html;
# 也可以把404请求直接301到某个域上
error_page 404 =301 https://xuexb.com/404;

这样就可以根据自己需求配置错误页为指定的状态码,因为非 200 的状态码可能会被浏览器拦截。


原文地址 : Nginx 状态码配置和错误文件
本站是作者语雀文档的镜像站, 如对文章有任何疑问请移步语雀进行 提问

[转] 关于 Nginx 下开启 php-fpm 输出 php 错误日志的设置

原文地址: 关于 Nginx 下开启 php-fpm 输出 php 错误日志的设置
最近在本地搭建的 LNMP 的开发环境。为了开发的时候不影响前端的正常开发就屏蔽的 PHP 里面 php.ini 中的一些错误提示。但是这样一来,就影响到了后端开发的一些问题比如不能及时调试开发中的一些问题。
nginx 与 apache 不一样,在 apache 中可以直接指定 php 的错误日志,那样在 php 执行中的错误信息就直接输入到 php 的错误日志中,可以方便查询。
在 nginx 中事情就变成了这样:nginx 只对页面的访问做 access 记录日志。不会有 php 的 error log 信息。nginx 把对 php 的请求发给 php-fpm fastcgi 进程来处理,默认的 php-fpm 只会输出 php-fpm 的错误信息,在 php-fpm 的 errors log 里也看不到 php 的 errorlog。
原因是 php-fpm 的配置文件 php-fpm.conf 中默认是关闭 worker 进程的错误输出,直接把他们重定向到/dev/null,所以我们在 nginx 的 error log 和 php-fpm 的 errorlog 都看不到 php 的错误日志。
所以我们要进行如下的设置就能查看到 nginx 下 php-fpm 不记录 php 错误日志的方法:
1,修改 php-fpm.conf 中的配置,如果没有请增加:

阅读更多

proxy_pass url 反向代理

说到 Nginx 就不得不说 Nginx 的反向代理是多么的好用,一个指令 proxy_pass 搞定反向代理,对于接口代理、负载均衡很是实用,但 proxy_pass 指令后面的参数很有讲究。
网上有很多什么绝对路径、相对路径的说法,其实在实际的应用中就分为两种情况:

阅读更多

配置 CORS 跨域

设置允许所有的请求

1
2
3
4
5
server {
location / {
add_header 'Access-Control-Allow-Origin' '*';
}
}

只允许GET请求

1
2
3
4
5
6
server {
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Request-Method' 'GET';
}
}

请求白名单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
location / {
# 白名单
if ($http_origin ~* (baidu\.com|github.xuexb.com)$) {
add_header 'Access-Control-Allow-Origin' '$http_origin';
# 允许cookie
add_header 'Access-Control-Allow-Credentials' true;
# 只允许某些方法
add_header 'Access-Control-Request-Method' 'GET, POST, OPTIONS';
# 支持获取其她字段, 需要前端设置 `xhr.withCredentials = true`
add_header 'Access-Control-Allow-Headers' 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
}

iconfont 字体跨域配置

1
2
3
4
5
6
7
server {
root xxx;
# 使用location来匹配以字体文件
location ~* \.(eot|otf|ttf|woff|svg)$ {
add_header Access-Control-Allow-Origin *;
}
}

但如果你的 location 已经配置了, 可以使用 if 判断添加, 如:

1
2
3
4
5
6
7
8
server {
location / {
# 使用判断请求文件来添加
if ($document_uri ~ \.(eot|otf|ttf|woff|svg)$) {
add_header Access-Control-Allow-Origin *;
}
}
}

原文地址 : 配置 CORS 跨域
本站是作者语雀文档的镜像站, 如对文章有任何疑问请移步语雀进行 提问

[转] 利用 nginx 来屏蔽指定的 user_agent 的访问

原文地址 : 利用 nginx 来屏蔽指定的 user_agent 的访问
对于做国内站的我来说,我不希望国外蜘蛛来访问我的网站,特别是个别垃圾蜘蛛,它们访问特别频繁。这些垃圾流量多了之后,严重浪费服务器的带宽和资源。通过判断 user agent,在 nginx 中禁用这些蜘蛛可以节省一些流量,也可以防止一些恶意的访问。
1、进入 nginx 的配置目录,例如 cd /usr/local/nginx/conf
2、添加 agent_deny.conf 配置文件 vim agent_deny.conf
加入以下

阅读更多

[转] Nginx 出现 413 Request Entity Too Large 错误解决方法

原文地址 : Nginx 出现 413 Request Entity Too Large 错误解决方法
Nginx 出现的 413 Request Entity Too Large 错误,这个错误一般在上传文件的时候出现
解决方法就是
打开 nginx 主配置文件 nginx.conf,一般在 /usr/local/nginx/conf/nginx.conf 这个位置,找到 http{}, 或者 server{} 段, 或者 location / {} 段,修改或者添加:

阅读更多

[转] nginx 配置 location 总结及 rewrite 规则写法

1. location 正则写法

一个示例:

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
location  = / {
# 精确匹配 / ,主机名后面不能带任何字符串
[ configuration A ]
}

location / {
# 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
# 但是正则和最长字符串会优先匹配
[ configuration B ]
}

location /documents/ {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
[ configuration C ]
}

location ~ /documents/Abc {
# 匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
[ configuration CC ]
}

location ^~ /images/ {
# 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
[ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif,jpg或jpeg 结尾的请求
# 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
[ configuration E ]
}

location /images/ {
# 字符匹配到 /images/,继续往下,会发现 ^~ 存在
[ configuration F ]
}

location /images/abc {
# 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
# F与G的放置顺序是没有关系的
[ configuration G ]
}

location ~ /images/abc/ {
# 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
[ configuration H ]
}

location ~* /js/.*/\.js
  • = 开头表示精确匹配
    如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。
  • ^~  开头表示 uri 以某个常规字符串开头,不是正则匹配
  • ~ 开头表示区分大小写的正则匹配;
  • ~* 开头表示不区分大小写的正则匹配
  • / 通用匹配, 如果没有其它匹配,任何请求都会匹配到

顺序 no 优先级:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分起始路径) > (/)
上面的匹配结果
按照上面的 location 写法,以下的匹配示例成立:

  • / -> config A
    精确完全匹配,即使/index.html 也匹配不了
  • /downloads/download.html -> config B
    匹配 B 以后,往下没有任何匹配,采用 B
  • /images/1.gif -> configuration D
    匹配到 F,往下匹配到 D,停止往下
  • /images/abc/def -> config D
    最长匹配到 G,往下匹配 D,停止往下
    你可以看到 任何以/images/开头的都会匹配到 D 并停止,FG 写在这里是没有任何意义的,H 是永远轮不到的,这里只是为了说明匹配顺序
  • /documents/document.html -> config C
    匹配到 C,往下没有任何匹配,采用 C
  • /documents/1.jpg -> configuration E
    匹配到 C,往下正则匹配到 E
  • /documents/Abc.jpg -> config CC
    最长匹配到 C,往下正则顺序匹配到 CC,不会往下到 E

实际使用建议

所以实际使用中,个人觉得至少有三个匹配规则定义,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass [http://tomcat](http://tomcat/):8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
proxy_pass [http://tomcat](http://tomcat/):8080/
}

http://tengine.taobao.org/book/chapter_02.html
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

2. Rewrite 规则

rewrite 功能就是,使用 nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 url 重写以及重定向。rewrite 只能放在server{}, location{}, if{} 中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如  [http://seanlook.com/a/we/index.php?id=1&u=str](http://seanlook.com/a/we/index.php?id=1&u=str)  只对/a/we/index.php 重写。语法rewrite regex replacement [flag];
如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用 proxy_pass 反向代理。
表面看 rewritelocation 功能有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获取资源的路径,而 location 是对一类路径做控制访问或反向代理,可以 proxy_pass 到其他机器。很多情况下 rewrite 也会写在 location 里,它们的执行顺序是:

  1. 执行 server 块的 rewrite 指令
  2. 执行 location 匹配
  3. 执行选定的 location 中的 rewrite 指令

如果其中某步 URI 被重写,则重新循环执行 1-3,直到找到真实存在的文件;循环超过 10 次,则返回 500 Internal Server Error 错误。

2.1 flag 标志位

  • last : 相当于 Apache 的[L]标记,表示完成 rewrite
  • break : 停止执行当前虚拟主机的后续 rewrite 指令集
  • redirect : 返回 302 临时重定向,地址栏会显示跳转后的地址
  • permanent : 返回 301 永久重定向,地址栏会显示跳转后的地址

因为 301 和 302 不能简单的只返回状态码,还必须有重定向的 URL,这就是 return 指令无法返回 301,302 的原因了。这里 last 和 break 区别有点难以理解:

  1. last 一般写在 server 和 if 中,而 break 一般使用在 location 中
  2. last 不终止_重写后_的 url 匹配,即新的 url 会再从 server 走一遍匹配流程,而 break 终止重写后的匹配
  3. break 和 last 都能组织继续执行后面的 rewrite 指令

2.2 if 指令与全局变量

if 判断指令
语法为if(condition){...},对给定的条件 condition 进行判断。如果为真,大括号内的 rewrite 指令将被执行,if 条件(conditon)可以是如下任何内容:

  • 当表达式只是一个变量时,如果值为空或任何以 0 开头的字符串都会当做 false
  • 直接比较变量和内容时,使用=!=
  • ~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的不匹配

-f!-f用来判断是否存在文件
-d!-d用来判断是否存在目录
-e!-e用来判断是否存在文件或目录
-x!-x用来判断文件是否可执行
例如:

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
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
} //如果cookie匹配正则,设置变量$id等于正则引用部分
if ($request_method = POST) {
return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
if ($slow) {
limit_rate 10k;
} //限速,$slow可以通过 set 指令设置
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
if ($args ~ post=140){
rewrite ^ http://[example.com/](http://example.com/) permanent;
} //如果query string中包含"post=140",永久重定向到example.com
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked [www.jefflei.com](http://www.jefflei.com/) [www.leizhenfang.com](http://www.leizhenfang.com/);
if ($invalid_referer) {
return 404;
} //防盗链
}

全局变量
下面是可以用作 if 判断的全局变量

  • $args : #这个变量等于请求行中的参数,同$query_string
  • $content_length : 请求头中的 Content-length 字段。
  • $content_type : 请求头中的 Content-Type 字段。
  • $document_root : 当前请求在 root 指令中指定的值。
  • $host : 请求主机头字段,否则为服务器名称。
  • $http_user_agent : 客户端 agent 信息
  • $http_cookie : 客户端 cookie 信息
  • $limit_rate : 这个变量可以限制连接速率。
  • $request_method : 客户端请求的动作,通常为 GET 或 POST。
  • $remote_addr : 客户端的 IP 地址。
  • $remote_port : 客户端的端口。
  • $remote_user : 已经经过 Auth Basic Module 验证的用户名。
  • $request_filename : 当前请求的文件路径,由 root 或 alias 指令与 URI 请求生成。
  • $scheme : HTTP 方法(如 http,https)。
  • $server_protocol : 请求使用的协议,通常是 HTTP/1.0 或 HTTP/1.1。
  • $server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
  • $server_name : 服务器名称。
  • $server_port : 请求到达服务器的端口号。
  • $request_uri : 包含请求参数的原始 URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
  • $uri : 不带请求参数的当前 URI,$uri 不包含主机名,如”/foo/bar.html”。
  • $document_uri : 与$uri 相同。

例:http://localhost:88/test1/test2/test.php

1
2
3
4
5
6
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php

2.3 常用正则

  • . : 匹配除换行符以外的任意字符
  • ? : 重复 0 次或 1 次
  • + : 重复 1 次或更多次
  • * : 重复 0 次或更多次
  • \d :匹配数字
  • ^ : 匹配字符串的开始
  • ` : 匹配字符串的介绍
  • {n} : 重复 n 次
  • {n,} : 重复 n 次或更多次
  • [c] : 匹配单个字符 c
  • [a-z] : 匹配 a-z 小写字母的任意一个

小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。

2.4 rewrite 实例

_例 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
http {
# 定义image日志格式
log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
# 开启重写日志
rewrite_log on;
server {
root /home/www;
location / {
# 重写规则信息
error_log logs/rewrite.log notice;
# 注意这里要用‘’单引号引起来,避免{}
rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)' /data?file=$3.$4;
# 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
set $image_file $3;
set $image_type $4;
}
location /data {
# 指定针对图片的日志格式,来分析图片类型和大小
access_log logs/images.log mian;
root /data/images;
# 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
try_files /$arg_file /image404.html;
}
location = /image404.html {
# 图片不存在返回特定的信息
return 404 "image not found\n";
}
}
}

对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,于是匹配到location /data,先看/data/images/test.png文件存不存在,如果存在则正常响应,如果不存在则重写 tryfiles 到新的 image404 location,直接返回 404 状态码。
_例 2_:

1
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;

对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配 location。
_例 3_:
见  ssl 部分页面加密
参考


原文地址 : [转] nginx 配置 location 总结及 rewrite 规则写法
本站是作者语雀文档的镜像站, 如对文章有任何疑问请移步语雀进行 提问

统计 Nginx 访问量

PV(Page View):即页面浏览量或者点击量,用户每一次对网站中每个页面访问均记录 1 个 PV。用户对同一页面的多次访问,访问量累积。
UV(Unique Visitor):指通过互联网浏览这个网页的人,电脑称为一个访客、手机也称为一个访客,一天之内相同的客户端只能被计算一次。
IP(Internet Protocol):指独立 IP 访问站点的 IP 总数,一天内相同 IP 只能算一次。
VV(Visit View):指所有访客一天内访问网站的次数,当访客完成所有浏览并最终关闭网站的所有页面时变完成了一次访问,同一访客一天内可能有多次访问行为,访问次数累积。
接下来看一下 Nginx 的配置文件:

/etc/nginx/nginx.conf
再看一下 access.log:

/var/log/nginx/access.log
access.log 文件里面的remote_user…等
查看各个访问量:
1.根据访问 IP 统计 UV

阅读更多

Node.js 反向代理

服务端如果使用nodejs运行服务,由于端口不能同时多个服务占用,而服务器中可能又是多个网站,那么可以使用 Nginx 做反向代理,比如有这些网站域名和端口:

域名 端口
www.xxoo.com 8001
www.xo.com 8002
www.xo.cn 8003

当然一个服务器上的网站可能还有更多,可以通过配置 Nginx 转发来代理这些端口分发,如:

阅读更多

配置泛域名转发

有的时候,我们需要配置一些自定义的子域名,如:

  • xuexb.user.demo.com
  • a01.user.demo.com

这时候就需要域名的 DNS 解析一个泛域名 *.user.demo.com 到服务器,Nginx 可以配置如下:

阅读更多

add_header 指令技巧

官方的介绍:

Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). The value can contain variables.
There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.
If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.

意思也就是说话在响应状态码成功时,add_header 指令才生效,并且当前《作用域》下没有 add_header 指令时,会向上层继承。
在使用过程中难免会遇到上级指令被覆盖的情况,如:

阅读更多

nginx 优化连接数


未优化之前的连接数 NotEstablished 的数量到达了一定的峰值, 然后处于持平状态, 在这个时候服务器日志会报 500 错误

这个地方考虑到的可能性是链接数过多导致的服务器
/etc/sysctl.conf

阅读更多

配置图片防盗链

防盗链是指当图片不是自己网站打开时返回 403 或者指定图片,是通过请求的来路判断是否是自己的站点来设置响应。

阅读更多