【Nginx17】Nginx学习:目录索引、字符集与浏览器判断模块

Nginx学习:目录索引、字符集与浏览器判断模块

今天要学习的内容有几个还是大家比较常见的,所以学习起来也不会特别费劲。对于目录的默认页设置大家都不会陌生,字符集的设置也比较常见,而浏览器的判断这一块,可能有同学会接触过针对 IE 浏览器的一些特殊设置。今天的内容也基本上都是可以在 http、server、location 中可以进行配置的,只有一个指令是只能在 http 中配置的,到时候会单独说。

默认页 index

没错,就是那个最常见的 index 指令,它是单独的属于 ngx_http_index_module 模块,不需要编译,是核心源码中的一个配置指令。不管是默认的 nginx.conf 还是用一些面板工具安装的 Nginx ,都会有这个指令的出现。

location / {root   html;index  index.html index.htm;
}

这就是默认配置中给的 index 指令的配置,如果是 PHP 环境,通常会把 index.php 放在前面。它的配置参数非常简单。

index file ...;

默认值是 index.html ,所以如果是静态页面,并且本身就有 index.html 这个文件的话,不配这个指令也行。它的作用就是定义如果是以 / 结尾的 location 路径,也就是目录路径,就会按照配置的顺序检查文件。比如上面的默认配置中,如果在 root 指定的根目录下没有 index.html 文件,就会找 index.htm 文件。如果有 index.html ,就直接会返回 index.html 文件了。那么如果这两个文件都找不到呢?404 呗。不过它还可以在最后一个元素带上一个有路径的文件,比如 /index.html 。现在我们就来配一个。

location /indextest/ {index index.html aaa.html a.txt /index.html;
}

注意,我们要在 root 指定的目录下创建一个 indextest 目录,否则即使最后有一个 /index.html ,也会一直是 404 。

mkdir /usr/local/nginx/html/indextest

现在这个目录里面没有配置中指定的这些文件,直接访问的话,就会返回根目录的首页文件。

接着我们可以一个一个地创建,比如先创建一个 a.txt ,再次访问,就会显示 a.txt 中的内容。这里的文件是可以自由定义的,不仅是 html 或者 txt 文本,php 之类的脚本文件都是可以的,前提是也要配好 FastCGI 。

另外需要注意的是,index 文件会引发内部重定向,请求可能会被其它 location 处理。 比如,下面这个例子:

location = / {index index.html;
}location / {...
}

请求 “/” 实际上将会在第二个 location 中作为 /index.html 被处理。这一段是官网的例子,我没有测试,其实就是 location 规则的问题。大家可以自己试试,意思就是 / 会变成 /index.html ,然后交由下面的 location 进行处理。

目录索引

有的时候,我们不指定 index ,而是需要直接列出整个目录里面的文件内容,就像一些开源代码的下载地址。比如说 Hadoop 的下载地址:https://archive.apache.org/dist/hadoop/common/

b160109b742277f8e5e7668365e87e92.png

在 Apache 中,也有类似的设置,而在 Nginx 中,只需要启用 ngx_http_autoindex_module 模块就可以了。这个模块也是核心源码中的,直接就可以使用。首先,还是要准备一些文件,比如可以用 shell 直接生成一些。

echo "this is 1.txt"{1..99}  >> /usr/local/nginx/html/indextest/1.txt

然后,就简单地配置一下,还是使用上面的 indextest 目录。

location /indextest/ {#index index.html aaa.html a.txt /index.html;autoindex on;
}

接下来直接访问 /indextest/ 路径,就可以看到下面的内容。

616ec6eeab51f1e5fdb293c03546a646.png

直接点击文件就可以打开访问对应的文件啦。

autoindex

开启或者关闭列出目录中文件的功能。

autoindex on | off;

默认是 off ,当然是不能随便把目录中所有的文件信息都暴露出来啦,因此,大部分情况下都只是特殊的一些目录才会用到。如果是 off ,并且没有 index ,也没有 index.html 的话,那就是 404 。

autoindex_exact_size

设置目录中列出的文件是显示精确大小,还是对KB,MB,GB进行四舍五入。

autoindex_exact_size on | off;

默认是 on ,也就是精确显示大小,设置成 off 的话,就会进行四舍五入带单位的显示。同时,它还必须是下面的 autoindex_format 设置为 html 时才会有效果。最后我们会一起看例子。

autoindex_format

设置索引目录展示的形式。

autoindex_format html | xml | json | jsonp;

默认是 html ,就是我们上面看到的那个样子,还可以换成别的形式。后面我们一起测试时看效果。

autoindex_localtime

设置目录中列出文件的时间是本地时间还是UTC时间。

autoindex_localtime on | off;

默认值是 off ,使用的是 UTC 时间,改成 on 之后,就是服务器的时间。

综合测试

现在直接配置上除上面的例子中没用到的那三个指令吧,如果是 on 的就换成 off ,off 的就换成 on ,html 也换成 json 。

autoindex_exact_size off;autoindex_format json;autoindex_localtime on;

看看效果,输出的结果是不是变成了下面这样的 json 格式了。

af552a86d728a44d1df4df27d4143ba5.png

但是大家会发现,size 表示的文件大小没有变化呀,前面说过了,autoindex_exact_size 只有在 html 的时候才会有效果。因此,我们还是要把 autoindex_format 换回 html ,这样就可以看到大小显示的结果也不一样了。

dbfb6b7c2aa784bce0f8ed6412814318.png

字符集 Charset

字符集的模块全名是 ngx_http_charset_module 模块。记得刚开始学 PHP 的时候,还是 PHP 刚刚升级到 5 的时候,5.2 或者 5.1 是主流版本,MySQL 也是同样的刚到 5 左右的版本。在哪个时代,Discuz 或者 DedeCMS 这些开源程序都会提供 UTF8 和 GBK 两种版本,是不是感觉怪怪的,因为当时 UTF8 还没有一统天下嘛。

到了现在,基本上不管是什么软件,PHP的编辑器创建的文件、MySQL建库建表、Redis、Go语言、Java、前端,等等等等,默认全是 UTF8 了,因此,字符集会产生的乱码问题说实话已经大大减少了。包括在 Nginx 中,默认的配置文件中那个默认的 server 里面,第四行就是一个被注释掉的 #charset koi8-r;配置。能写在默认配置文件中,说明还是比较常用的,而被注释掉了,说明现在默认可能并不是完全需要了。总之,我们不敢说它一定是很重要,但确实是一个不能忽略的配置项。

咱们的测试,就设置一个 gbk ,让 utf8 乱码好了,默认的 koi8-r 我都不知道是哪里的语言编码....

charset gbk;

继续复用上面的 /indextest/ 这个路径,在 location 添加上面的这条配置指令。然后随便建立一个文件,并且在里面写中文,看看访问结果是不是乱码了。其实呀,这个指令的意思是在响应头的 Content-type 中添加上 charset 参数。

默认情况下,我们访问的普通 Nginx 静态页面返回的 Content-type 就是一个 text/html ,而设置了 charset 之后,就变成了 text/html;charset=gbk 了。现在大部分情况下不需要设置,如果不设置,默认浏览器就会使用 UTF8 ,同时访问的文件也是 UTF8 的,这样就没啥问题了。另外如果是 PHP ,除去文件编辑器和普通创建的文件都会使用 UTF8 编码外,很多框架以及我们自己写 Demo 时,也会这样加上一段。

// php文件
header("Content-type: text/html; charset=utf-8");

当使用代理或者 FastCGI 时,默认情况下会直接使用它们返回的响应头中的 Content-type 。

charset

为响应头的 “Content-Type” 添加指定的字符集。

charset charset | off;

现在的默认值就是 off ,表明不在响应头的 “Content-Type” 中添加字符集。如果这个字符集和 source_charset 指令设置的字符集不同,就会进行转换。这个指令后面马上就会说。

它的参数也可以使用变量来指定,参数可以使用的值需要符合 charset_map 或 source_charset 的值。此外,字符集也可以在响应头的 “X-Accel-Charset” 中设置。 这个功能可以使用 proxy_ignore_headers和 fastcgi_ignore_headers 指令来禁用。

charset_map

描述了从一个字符集到另一个字符集的转换表。这个配置指令只能配置在 http 模块中,不能放到 server 或 location 里面。

charset_map charset1 charset2 { ... }

默认值是空的,意思就是从 charset1 到 charset2 的转换,比如说 UTF8 到 GBK 的转换规则,配置比较复杂,比如这样:

charset_map koi8-r utf-8 {C0 D18E ; # small yuC1 D0B0 ; # small aC2 D0B1 ; # small bC3 D186 ; # small ts...
}

我们下载的安装包中已经提供了从koi8-r到 windows-1251,从koi8-rutf-8,以及从 windows-1251utf-8的完整转换表。都不是我们常用的,这一块大家了解一下就好啦。

charset_types

使模块在响应时能处理除了 “text/html” 之外其他指定的MIME类型。

charset_types mime-type ...;

默认值包含 text/html text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml 这些。这个配置其实和我们上篇文章中学过的 addition_types 一样,就是说这些类型的会让 charset 指令产生效果,如果有特殊需求可以再继续添加。

override_charset

对于接收到的代理服务器或者 FastCGI 服务器的响应头中 “Content-Type” 已经带有字符集的情况,确定是否进行字符集转换。

override_charset on | off;

默认值是 on ,如果开启转换,接收到的响应中指定的字符集会被当作原始字符集。如果在子请求中接收到的应答,始终会将应答的字符集转换为主请求的字符集,无论 override_charset 指令是否开启。

我拿 PHP 试了,没啥效果,会直接报 500 错误,PHP 中使用 header 指定字符集为 UTF8 ,然后 Nginx 中设置的 Charset 还是 gbk 。错误信息是指定的字符集在 charset_map 或 source_charset 中不存在。也没找到合适的 UTF8 转换 GBK 的 charset_map 文件,所以这一块也就不知道怎么继续测试啦。有了解的小伙伴记得评论留言哦。

source_charset

定义响应中的原始字符集。

source_charset charset;

默认是空的,没有设置。如果这个指令配置的字符集与 charset 配置的不一样,就会进行转换。

浏览器判断 browser

在浏览器判断的 ngx_http_browser_module 模块中,有一个变量你肯定见过,那就是 $msie 这个变量。用于判断当前请求过来的浏览器是不是 IE 浏览器,如果是的话,这个变量的值就会变成 1 。

除了这个变量之外,这个模块里面还提供了三个变量,另外还有几个指令,是对这几个变量进行配置以及赋值的。也就是说,整个模块其实都围绕下面的这三个变量。

  • $modern_browser 如果浏览器被为识别为新式浏览器,该值等于 modern_browser_value 指令设置的值。

  • $ancient_browser 如果浏览器被识别为旧式浏览器,该值等于 ancient_browser_value 指令设置的值。

  • $msie 如果浏览器被识别为任何版本的MSIE,该值等于 “1” 。

这些变量有啥用呢?别急,后面测试的时候再看,先来看看在这个模块中的配置指令,一共就四个。

ancient_browser

如果任一指定的子串在请求头的“User-Agent”域中被发现,浏览器将被认定为旧式浏览器。

ancient_browser string ...;

它的默认值是空的,没有默认值,而另外一个 ancient_browser_value 配置的默认值是 1 ,也就说,如果使用普通的 if 不带等于的进行布尔判断,那么 $ancient_browser 将一直返回 1 。这个我们后面测试时会见到效果。

ancient_browser_value

设定变量 $ancient_browser 的值。

ancient_browser_value string;

上个指令中就介绍过了,它的默认值是 1 ,当然也可以设置成别的值,而且不一定是数字,字符串也可以。可以用在 if 判断上。但是如果直接设置了这个值,那么后续任何别的操作都没用了,$ancient_browser 会一直是这个配置指令设置的值。

modern_browser

指定一个版本,此版本及后续版本的浏览器都被认定为新式浏览器。

modern_browser browser version;
modern_browser unlisted;

浏览器可以是下列之一: msie, gecko (基于Mozilla), opera,safari, 或者 konqueror 。注意这里没有 Chrome 哦,Chrome 也是基于 Mozilla 的,因此用 gecko 就可以了。

版本可被指定为以下形式:X, X.X, X.X.X, 或 X.X.X.X。 每一形式的最大值分别是4000, 4000.99, 4000.99.99, 和 4000.99.99.99 。

如果浏览器既没有在 modern_browser 中列出,又没有在 ancient_browser 中列出时,并且配置了特殊值 unlisted ,那么浏览器将被认定为新式浏览器,否则认定为旧式浏览器。 如果请求头中没有 “User-Agent” 域,浏览器以没有列出对待。

看着有点懵吧?其实它就是和 ancient_browser 反过来的,马上在例子中我们就可以看到效果。

modern_browser_value

设定变量 $modern_browser 的值。

modern_browser_value string;

和 ancient_browser_value 的意思是一样的,它的默认值同样也是 1 ,但是,注意 modern_browser 定义中说的那些内容,如果是默认情况下,modern_browser 是空的,即使你下载最新版本的浏览器也不会判断为新式浏览器,因此,最终 $modern_browser 的值在默认情况下其实是个空的。

测试 browser

看上面的变量和配置项有点晕吧?其实这一块就是帮助我们用自己定义的标准来判断指定的浏览器,将这个浏览器归属到 新式 或 旧式 浏览器这两个阵营中。然后使用两个变量就可以通过 Nginx 中的编程语法,比如 if 来进行一些特殊的判断。

location /browsertest/ {add_header Content-Type text/plain;#ancient_browser_value 0;modern_browser safari 600.0.0;ancient_browser safari;if ($ancient_browser) {#return 301 /indextest/1.txt;}return 200 $modern_browser,$ancient_browser,$msie;
}

在上面的例子中,先不看注释的部分。modern_browser 我们设置了一个 safari ,版本号是 600.0.0 ,意思就是只要是大于等于这个版本的 safari 浏览器,就会判定为新式浏览器,$modern_browser 会变成 1 ,而 $ancient_browser 会变成空的字符串。反过来,如果不是 safari 浏览器,或者版本小于指定的版本号,上面两个变量的值就会反过来。最后,我们通过 return 直接打印这三个变量的值。

怎么测试呢?我们可以通过 Postman 来重写请求头的 User-Agent 字段实现。

70ce743a27820a6d9dd61709eb01d4fa.png

这一大串的字符怎么来的?拿真的浏览器请求一下,然后用开发者工具查看请求头复制出来嘛。然后我们就好操作了,直接更改这一段字符串中最后的那个版本号标识就好啦。

截图中的这个版本号,返回的结果是 ",1," 这样的内容。而如果我们改成 600.1.15 ,结果就会变成 "1,," 这样。

接着,我们可以打开上面代码中 if 代码段内的注释,如果判定为 旧式 浏览器,那么就直接 return 进行 301 跳转到最开始的 indextest 目录,并打开 1.txt 文件。这就是模拟我们可能会对一某些浏览器有一些特殊的操作。如果判定不是 旧式 浏览器的话,还是正常返回那三个变量的值。这就是变量在 Nginx 编程中的重要作用。

这个 if 是不是很像我们的编程语法呀?但其实,它也是个配置指令,或者你可以将整个 Nginx 中的配置指令都看成是一种编程语言的语法。就像 HTML 是超文本标记语言一样,Nginx 的配置指令可以说也是构建在主体的 C/C++ 程序之上的一套配置标记语言。关于 if 更详细的内容,在后面的重写模块中会再详细的学习。

最后上面那个 ancient_browser_value 注释大家也可以打开试下,不出意外的话,现在你怎么修改版本号,怎么配其它的指令,一直都会是 ",0," 这样的返回结果。

总结

没骗大家吧?index 和 charset 肯定是大家比较常见的配置指令。而且是非常常见,index 在默认的配置文件中就有,而 charset 虽然没有直接给出,但在默认配置文件的注释中也能看到,这就说明它也真的是非常常用的一种配置指令。另外就是 $msie 这个变量估计不少同学是见过的,也可能在你的项目就就会对 IE 进行一些特殊的处理。

好了,继续接下来的学习吧,这样刷文档的感觉咋样?反正我现在发现官方文档真的是我们的第一学习神器哦!

参考文档:

http://nginx.org/en/docs/http/ngx_http_index_module.html

http://nginx.org/en/docs/http/ngx_http_autoindex_module.html

http://nginx.org/en/docs/http/ngx_http_charset_module.html

http://nginx.org/en/docs/http/ngx_http_browser_module.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/94004.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode ——二叉树篇(三)

刷题顺序及思路来源于代码随想录,网站地址:https://programmercarl.com 二叉树的定义及创建见: LeetCode ACM模式——二叉树篇(一)_要向着光的博客-CSDN博客 目录 116. 填充每个节点的下一个右侧节点指针 117. 填…

Doris2.0时代的一些机遇和挑战!

300万字!全网最全大数据学习面试社区等你来! 上个周五的时候,Doris官宣了2.0版本,除了在性能上的大幅提升,还有一些特性需要大家特别关注。 根据官网的描述,Doris在下面领域都有了长足进步: 日志…

python的 __all__ 用法

一、介绍 在Python中,__all__通常用于定义模块的公开接口。在使用from module import *语句时,此时被导入模块若定义了__all__属性,则只有__all__内指定的属性、方法、类可被导入;若没定义,则导入模块内的所有公有属性…

嵌入式系统中如何选择RTC电池?

RTC(Real Time Clock)是一种用于提供系统时间的独立定时器,它可以在系统断电或低功耗模式下继续运行,只需要一个后备电池作为供电源。在嵌入式系统中,选择合适的RTC电池时非常关键的,它会影响系统时间的准确…

pyqt和ros结合使用接受相机和点云消息并展示(附代码)

代码是 ROS 节点的 Python QT脚本,用于订阅 /turtle1/cmd_vel、/tracking_image 和 /test_pointcloud 话题。 脚本首先通过 ps 命令检查是否已启动 ROS 主节点,如果没有则启动一个新的 ROS 主节点。然后,它订阅 /turtle1/cmd_vel、/tracking_image 和 /test_pointcloud 话题…

Git 常用操作

一、Git 常用操作 1、Git 切换分支 git checkout命令可以用于三种不同的实体:文件,commit,以及分支。checkout的意思就是对于一种实体的不同版本之间进行切换的操作。checkout一个分支,会更新当前的工作空间中的文件,…

【日常积累】HTTP和HTTPS的区别

背景 在运维面试中,经常会遇到面试官提问http和https的区别,今天咱们先来简单了解一下。 超文本传输协议HTTP被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果…

爬虫逆向实战(十三)--某课网登录

一、数据接口分析 主页地址:某课网 1、抓包 通过抓包可以发现登录接口是user/login 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以发现有一个password加密参数,还有一个browser_key这个可以写死不需要关心 请求头…

draw.io导出矢量图到word报错text is not svg - cannot display

先参考https://blog.csdn.net/a625750076/article/details/126384831 如果不行,可能是转存的问题 解决方法:直接在draw.io上操作 第一步 第二步 然后再word中粘贴,依旧是矢量图哦!

494. 目标和

494. 目标和 原题链接:完成情况:解题思路:数组回溯法动态规划 参考代码:数组回溯法__494目标和__动态规划 经验吸取 原题链接: 494. 目标和 https://leetcode.cn/problems/target-sum/description/ 完成情况&#…

09- DMA(DirectMemoryAccess直接存储器访问)

DMA 09 、DMA(DirectMemoryAccess直接存储器访问)DMA配置流程 09 、DMA(DirectMemoryAccess直接存储器访问) DMA配置流程 dma.c文件 main.c文件 详见《stm32中文参考手册》表57。

Redis_主从复制

8. 主从复制 8.1 简介 主从库采用读写分离的方式 读操作:主库、从库都可以处理写操作:首先写到主库执行,然后再将主库同步给从库。 实现读写分离,性能扩展 容灾快速恢复 8.2 主从复制步骤 创建一个目录 ,在root下创建一个m…

Snapdragon 8 Gen 3:详解骁龙最新一代处理器的性能与特点

Snapdragon 8 Gen 3正在为下一波最好的安卓手机提供动力。高通的旗舰移动芯片组长期以来一直是安卓手机中最好的芯片组之一,但它在一系列关键领域总是落后于苹果的A系列芯片——A17仿生芯片看起来也不例外。 Snapdragon 8 Gen 2和Galaxy芯片的Gen 2确实缩小了差距…

Centos 防火墙命令

查看防火墙状态 systemctl status firewalld.service 或者 firewall-cmd --state 开启防火墙 单次开启防火墙 systemctl start firewalld.service 开机自启动防火墙 systemctl enable firewalld.service 重启防火墙 systemctl restart firewalld.service 防火墙设置开…

分布式 - 消息队列Kafka:Kafka生产者发送消息的分区策略

文章目录 01. Kafka 分区的作用02. PartitionInfo 分区源码03. Partitioner 分区器接口源码04. 自定义分区器05. 默认分区器 DefaultPartitioner06. 随机分区分配 RoundRobinPartitioner07. 黏性随机分区分配 UniformStickyPartitioner08. 为什么Kafka 2.4 版本后引入黏性分区策…

尚硅谷大数据项目《在线教育之离线数仓》笔记001

视频地址:尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 P003 P004【数仓概念讲的颇为详细】 P018 P019 P020 P021 P022 P023 P024 P003 时间切片:时间回溯,找回以前的数据。 P004【数仓概念讲的颇为详细】 核心架…

07微服务的事务管理机制

一句话导读 在单体应用程序中,事务通常是在单个数据库或单个操作系统中管理的,而在微服务架构中,事务需要跨越多个服务和数据库,这就使得事务管理变得更加复杂和困难。 目录 一句话导读 一、微服务事务管理的定义和意义 二、微…

Kali Linux中常用的渗透测试工具有哪些?

今天我们将继续探讨Kali Linux的应用,这次的重点是介绍Kali Linux中常用的渗透测试工具。Kali Linux作为一款专业的渗透测试发行版,拥有丰富的工具集,能够帮助安全专家和渗透测试人员检测和评估系统的安全性。 1. 常用的渗透测试工具 以下是…

开源数据库Mysql_DBA运维实战 (修改root密码)

MySQL——修改root密码的4种方法 本文以windows为例为大家详细介绍下MySQL修改root密码的4种方法,大家可以可以根据的自己的情况自由选择,希望对大家有所帮助 方法1: 用SET PASSWORD命令 首先登录MySQL。 格式:mysql> set pass…

半导体退火那些事(3)

4.半导体退火设备 双腔全自动兼容6-8寸快速退火炉RTP 产地:中国 型号: S803 特点: 室温到1250C,应用于SiC,GaN等第三代半导体领域 简介 (Description) S803系列自动快速退火炉,内置Robot可以自动取放片,适用于最大8英寸 (单片200m…