强制使用小写的 url 地址

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

阅读更多

Nginx Gzip 压缩使用和详解

网站的性能部分取决于用户浏览器下载的所有文件的大小。减小这些传输文件的大小可以使网站更快。对于那些在按流量计费的连接上支付带宽使用费的人来说,它还可以使网站成本更低。
gzip 是一种流行的数据压缩程序。可以配置 Nginx 用于动态压缩它提供的文件。然后,这些文件在使用时由支持它的浏览器解压缩,没有任何损失,但可以在Web服务器和浏览器之间传输更少的数据量。好消息是,所有主流浏览器都支持
由于压缩的一般工作方式,某些文件压缩得比其他文件更好。例如,文本文件压缩得很好,通常最终会缩小两倍以上。另一方面,JPEG或PNG文件等图像已经按其性质进行了压缩,并且使用二次压缩很少或根本没有结果。另外压缩文件会耗费服务器资源,所以只压缩可以压缩的文件。
Nginx实现资源压缩的原理是通过 ngx_http_gzip_module 模块拦截请求,并对需要做 gzip 的类型做 gzip,ngx_http_gzip_module 是Nginx默认集成的,不需要重新编译,直接开启

阅读更多

Nginx broti 压缩算法

这里仅仅是对 Broti 算法进行简要的对比和描述, 不涉及到实际使用

在web应用中,为了节省流量,降低传输数据大小,提高传输效率,常用的压缩方式一般都是gzip,今天我们来介绍另外一种更高效的压缩方式brotli。
Brotli 是基于LZ77算法的一个现代变体、霍夫曼编码和二阶上下文建模。Google软件工程师在2015年9月发布了包含通用无损数据压缩的Brotli增强版本,特别侧重于HTTP压缩。
注意:使用算法的前提是启用了 https,因为 http 请求中 request header 里的 Accept-Encoding: gzip, deflate 是没有 br 的。
关于Brotli 算法详细请查看:https://zh.wikipedia.org/wiki/Brotli

阅读更多

配置 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 中的配置,如果没有请增加:

阅读更多

Nginx 简介

image.png
Nginx(发音同 engine x)是一个异步框架的 Web 服务器,也可以用作反向代理,负载平衡器 和 HTTP 缓存。该软件由 Igor Sysoev 创建,并于 2004 年首次公开发布。同名公司成立于 2011 年,以提供支持。Nginx 是一款免费的开源软件,根据类 BSD 许可证的条款发布。一大部分 Web 服务器使用 Nginx ,通常作为负载均衡器。

阅读更多

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 编译参数

命令

nginx -V
查看当前已安装版本的编译参数

nginx version: nginx/1.21.6
built by clang 13.0.0 (clang-1300.0.29.30)
built with OpenSSL 1.1.1m 14 Dec 2021 (running with OpenSSL 1.1.1o 3 May 2022)
TLS SNI support enabled
configure arguments:

配置参数

参数名称 备注
--prefix=value 指向安装目录
--sbin-path 指向(执行)程序文件(nginx
--conf-path= 指向配置文件(nginx.conf
--error-log-path= 指向错误日志目录
--pid-path= 指向 pid文件(nginx.pid
--lock-path= 指向 lock文件(nginx.lock)(安装文件锁定,防止安装文件被别人利用,或自己误操作。)进程 ID 文件
--user= 指定程序运行时的用户名
--group= 指定程序运行时的用户组名
--builddir= 指向编译目录
--with-rtsig_module 启用 rtsig 模块支持(实时信号)
--with-select_module 启用 select 模块支持(一种轮询模式,不推荐在高载环境下使用)禁用:--without-select_module
--with-poll_module 启用 poll 模块支持(功能与 select 相同,与 select 特性相同,为一种轮询模式,不推荐在高载环境下使用)
--with-file-aio 启用 file aio 支持(一种 APL 文件传输格式)
--with-ipv6 启用 ipv6 支持
--add-module= 启用外部模块支持
--with-cc= 指向 C 编译器路径
--with-cpp= 指向 C 预处理路径
--with-cc-opt= 设置 C 编译器参数
--with-ld-opt= 设置连接文件参数
--with-cpu-opt= 指定编译的 CPU,可用的值为:pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64
--without-pcre 禁用 PCRE 库
--with-pcre 启用 PCRE 库
--with-pcre= 指向 PCRE 库文件目录
--with-pcre-opt= 在编译时为 PCRE 库设置附加参数
--with-md5= 指向 MD5 库文件目录(消息摘要算法第五版,用以提供消息的完整性保护)
--with-md5-opt= 在编译时为 MD5 库设置附加参数
--with-md5-asm 使用 MD5 汇编源
--with-sha1= 指向 sha1 库目录(数字签名算法,主要用于数字签名)
--with-sha1-opt= 在编译时为 sha1 库设置附加参数
--with-sha1-asm 使用 sha1 汇编源
--with-perl= 设定 perl 库文件路径
--with-zlib= 指向 zlib 库目录
--with-zlib-opt= 在编译时为 zlib 设置附加参数
--with-zlib-asm= 为指定的 CPU 使用 zlib 汇编源进行优化,CPU 类型为 pentium, pentiumpro
--with-libatomic 为原子内存的更新操作的实现提供一个架构
--with-libatomic= 指向 libatomic_ops 安装目录
--with-openssl= 指向 openssl 安装目录
--with-openssl-opt 在编译时为 openssl 设置附加参数
--with-debug 启用 debug 日志
--with-http_ssl_module 启用 ngx_http_ssl_module 支持(使支持 HTTPS 请求,需已安装 openssl)
--with-http_realip_module 启用 ngx_http_realip_module 支持(这个模块允许从请求标头更改客户端的 IP 地址值,默认为关)
--with-http_addition_module 启用 ngx_http_addition_module 支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求)
--with-http_xslt_module 启用 ngx_http_xslt_module 支持(过滤转换 XML 请求)
--with-http_image_filter_module 启用 ngx_http_image_filter_module 支持(传输 JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。GD 库要用到)
--with-http_geoip_module 启用 ngx_http_geoip_module 支持(该模块创建基于与 MaxMind GeoIP 二进制文件相配的客户端 IP 地址的 ngx_http_geoip_module 变量)
--with-http_sub_module 启用 ngx_http_sub_module 支持(允许用一些其他文本替换 Nginx 响应中的一些文本)
--with-http_dav_module 启用 ngx_http_dav_module 支持(增加 PUT、DELETE、MKCOL 创建集合,COPY 和 MOVE 方法)默认情况下为关闭,需编译开启
--with-http_flv_module 启用 ngx_http_flv_module 支持(提供寻求内存使用基于时间的偏移量文件)
--with-http_gzip_static_module 启用 ngx_http_gzip_static_module 支持(在线实时压缩输出数据流)
--with-http_random_index_module 启用 ngx_http_random_index_module
支持(从目录中随机挑选一个目录索引)
--with-http_secure_link_module 启用 ngx_http_secure_link_module 支持(计算和检查要求所需的安全链接网址)
--with-http_degradation_module 启用 ngx_http_degradation_module 支持(允许在内存不足的情况下返回 204 或 444 码)
--with-http_stub_status_module 启用 ngx_http_stub_status_module 支持(获取 Nginx 自上次启动以来的工作状态)
--without-http_charset_module 禁用 ngx_http_charset_module 支持(重新编码 WEB 页面,但只能是一个方向–服务器端到客户端,并且只有一个字节的编码可以被重新编码)
--without-http_gzip_module 禁用 ngx_http_gzip_module 支持(该模块同 --with-http_gzip_static_module
功能一样)
--without-http_ssi_module 禁用 ngx_http_ssi_module 支持(该模块提供了一个在输入端处理处理服务器包含文件(SSI)的过滤器,目前支持 SSI 命令的列表是不完整的)
--without-http_userid_module 禁用 ngx_http_userid_module 支持(该模块用来处理用来确定客户端后续请求的 cookie
--without-http_access_module 禁用 ngx_http_access_module 支持(该模块提供了一个简单的基于主机的访问控制。允许/拒绝基于 IP 地址)
--without-http_auth_basic_module 禁用 ngx_http_auth_basic_module(该模块是可以使用用户名和密码基于 HTTP 基本认证方法来保护你的站点或其部分内容)
--without-http_autoindex_module 禁用 ngx_http_autoindex_module 支持(该模块用于自动生成目录列表,只在 ngx_http_index_module
模块未找到索引文件时发出请求。)
--without-http_geo_module 禁用 ngx_http_geo_module 支持(创建一些变量,其值依赖于客户端的 IP 地址)
--without-http_map_module 禁用 ngx_http_map_module 支持(使用任意的键/值对设置配置变量)
--without-http_split_clients_module 禁用 ngx_http_split_clients_module 支持(该模块用来基于某些条件划分用户。条件如:ip 地址、报头、cookies 等等)
--without-http_referer_module 禁用 ngx_http_referer_module 支持(该模块用来过滤请求,拒绝报头中 Referer 值不正确的请求)
--without-http_rewrite_module 禁用 ngx_http_rewrite_module ,链接重写
--without-http_proxy_module 禁用 ngx_http_proxy_module 支持(有关代理服务器)
--without-http_fastcgi_module 禁用 ngx_http_fastcgi_module 支持(该模块允许 Nginx 与 FastCGI 进程交互,并通过传递参数来控制 FastCGI 进程工作。 )FastCGI 一个常驻型的公共网关接口。
--without-http_uwsgi_module 禁用 ngx_http_uwsgi_module 支持(该模块用来医用 uwsgi 协议,uWSGI 服务器相关)
--without-http_scgi_module 禁用 ngx_http_scgi_module 支持
--without-http_memcached_module 禁用 ngx_http_memcached_module 支持(该模块用来提供简单的缓存,以提高系统效率)
-without-http_limit_zone_module 禁用 ngx_http_limit_zone_module 支持(该模块可以针对条件,进行会话的并发连接数控制)
--without-http_limit_req_module 禁用 ngx_http_limit_req_module 支持(该模块允许你对于一个地址进行请求数量的限制用一个给定的 session 或一个特定的事件)
--without-http_empty_gif_module 禁用 ngx_http_empty_gif_module支持(该模块在内存中常驻了一个 1*1 的透明 GIF 图像,可以被非常快速的调用)
--without-http_browser_module 禁用 ngx_http_browser_module 支持
--without-http_upstream_ip_hash_module 禁用 ngx_http_upstream_ip_hash_module 支持(该模块用于简单的负载均衡)
--with-http_perl_module 启用 ngx_http_perl_module 支持(该模块使 nginx 可以直接使用 perl 或通过 ssi 调用 perl)
--with-perl_modules_path= 设定 perl 模块路径
--http-log-path= 设定 access log 路径
--http-client-body-temp-path= 设定 HTTP 客户端请求临时文件路径
--http-proxy-temp-path= 设定 HTTP 代理临时文件路径
--http-fastcgi-temp-path= 设定 HTTP Fastcgi 临时文件路径
--http-uwsgi-temp-path= 设定 HTTP uwsgi 临时文件路径
--http-scgi-temp-path= 设定 HTTP scgi 临时文件路径
--without-http 禁用 HTTP server 功能
--without-http-cache 禁用 HTTP Cache 功能
--with-mail 启用 POP3/IMAP4/SMTP 代理模块支持
--with-mail_ssl_module 启用 ngx_mail_ssl_module 支持
--without-mail_pop3_module 禁用 POP3 协议
--without-mail_imap_module 禁用 IMAP 协议
--without-mail_smtp_module 禁用 SMTP 协议
--with-google_perftools_module 启用 ngx_google_perftools_module 支持(调试用,剖析程序性能瓶颈)
--with-cpp_test_module 启用 ngx_cpp_test_module 支持

部分摘自:http://www.ttlsa.com/nginx/nginx-configure-descriptions/


原文地址 : Nginx 编译参数
本站是作者语雀文档的镜像站, 如对文章有任何疑问请移步语雀进行 提问

[转] 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

阅读更多

Mac 编译 Nginx 并增加 echo 模块

方法 1 : 使用 openrestry

安装地址 : http://openresty.org/en/installation.html

1
$ brew install openresty/brew/openresty

如果是 nginx 也安装了, 可以停掉 nginx , 将配置文件复制到 openresty 文件夹 /usr/local/etc/openresty , 启动 openresty 即可运行

1
2
$ brew services stop nginx
$ brew services start openresty/brew/openresty

编译 echo module 并加载(失败)

!!! 此方法不能使用, 仅仅作为记录

解压源文件
Nginx 目录 : /usr/local/share/nginx/src
包含的文件列表

1
2
-rw-r--r--  1 duoli  staff   1.4K  8 11 22:52 configure_args.txt
-rw-r--r-- 1 duoli staff 658K 8 11 22:52 src.tar.xz

解压 源文件

1
2
$ xz -dk src.tar.xz
$ tar -zxvf src.tar

查看编译参数

1
2
3
4
$ cat configure_args.txt
...
--sbin-path=/usr/local/Cellar/nginx/1.19.2/bin/nginx
...

下载 echo module
当前目录: /usr/local/share/nginx/src/

1
2
3
$ mkdir modules
$ cd modules
$ git clone https://github.com/openresty/echo-nginx-module

我们编译的基础之上在加上 echo 目录, 由于无需覆盖, 所以这里修改 nginx 的文件目录 --sbin-path=/usr/local/Cellar/nginx/1.19.2/bin/nginx-echo
这里增加编译参数 --with-echo-module=/usr/local/share/nginx/src/modules/echo-nginx-module
这里使用 echo 官方使用动态模块加入:
https://github.com/openresty/echo-nginx-module#installation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ./configure --prefix=/usr/local/Cellar/nginx/1.19.2 \
--add-dynamic-module=/usr/local/share/nginx/src/modules/echo-nginx-module \
--with-cc-opt='-DNGX_HTTP_HEADERS' $(nginx -V)
checking for OS
+ Darwin 19.6.0 x86_64
checking for C compiler ... found
+ using Clang C compiler
+ clang version: 11.0.3 (clang-1103.0.32.62)
...
...
creating objs/Makefile
Configuration summary
+ using system PCRE library
+ OpenSSL library is not used
+ using system zlib library
nginx path prefix: "/usr/local/Cellar/nginx/1.19.2"
nginx binary file: "/usr/local/Cellar/nginx/1.19.2/sbin/nginx"
nginx modules path: "/usr/local/Cellar/nginx/1.19.2/modules"
...
$ make -j2
$ make install

这样存在动态模块 /usr/local/Cellar/nginx/1.19.2/modules

1
2
$ ll
-rwxr-xr-x 1 duoli staff 49K 8 25 17:08 ngx_http_echo_module.so

nginx 配置加载动态模块
但是这样加载的模块出现 不兼容

1
nginx: [emerg] module "/usr/local/Cellar/nginx/1.19.2/modules/ngx_http_echo_module.so" is not binary compatible in /usr/local/etc/nginx/nginx.conf:11

原因可能是版本不兼容: https://github.com/openresty/echo-nginx-module#compatibility


原文地址 : Mac 编译 Nginx 并增加 echo 模块
本站是作者语雀文档的镜像站, 如对文章有任何疑问请移步语雀进行 提问

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 指令时,会向上层继承。
在使用过程中难免会遇到上级指令被覆盖的情况,如:

阅读更多