【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 yu
    C1 D0B0 ; # small a
    C2 D0B1 ; # small b
    C3 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

XenDesktop5.6如何连接数据库

Citrix在数据库的连接方式上一直不统一,但是也还是有迹可循的。 经过了好长时间的下载以后,今天终于有时间来测试一下最新版本的XenDesktop 5 SP1,由于结合了其他组件和环境的需要,所以,选择了独立部署数据库&#xf…

【学习笔记之opcua】使用Python获取opcua数据

Python与OPC UA的应用 示例代码 将代码放入spyder中运行后,出现下面这个错误 没有‘opcua’,那我们就下载pip install opcua 之后出现下面这个错误 问问题大不,安装语句写错了 正经安装语句是 !pip install opcua 读取opcua协议数据测试 …

若依框架给字典字段新增color值,并且实现下拉列表选项进行颜色设置

首先获取所要新增的字典,并且根据字典的value值选取对应的颜色参数 this.getDicts("risk_level").then(response > {const color {mild:#F1F4BD,moderate:#EEC920,severe:#FF6C0D,very_severe:#FF0000,no_harm:green};const res response.data.map(…

深兰科技熊猫汽车牵手首恒出行,人工智能技术提升商用车运营服务

8月8日,深兰科技集团旗下熊猫新能源汽车(上海)有限公司(下称熊猫新能源汽车)与河南首恒出行服务有限公司(下称首恒出行)在深兰科技总部举行签约仪式,首恒出行将向熊猫新能源汽车年定向采购10000台商用车,双方将在汽车后市场领域进行技术合作。…

如何在出差期间远程访问企业ERP系统?内网穿透解决您的难题!

文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻,不管是财务、生产、销售还是采购,都需要用到ERP系统来协助。…

动画制作选择Blender还是Maya

Blender和Maya是两种最广泛使用的 3D 建模和动画应用程序。许多经验丰富的用户表示,Blender 在雕刻工具方面远远领先于 Maya,并且在 3D 建模方面达到了相同的质量水平。对于刚接触动画行业的人来说,您可能会问“我应该使用 Blender 还是 Maya…

【操作系统】24王道考研笔记——第一章 计算机系统概述

第一章 计算机系统概述 一、操作系统基本概念 1.1 定义 1.2 特征 并发 (并行:指两个或多个事件在同一时刻同时发生) 共享 (并发性指计算机系统中同时存在中多个运行着的程序,共享性指系统中的资源可供内存中多个并…

网络连接(3次握手和4次挥手)

在进行3次握手和4次挥手传输数据时,都可能会出现丢包的情况,推荐看出现丢包问题的情况以及解决方法 一.为什么要进行3次握手? 在进行网络连接时,需要3次握手 3次握手的初心就是两方面: 1.投石问路,验证通…

HDMI接口的PCB布局布线要求

高清多媒体接口(High Definition Multimedia Interface),简称:HDMI,是一种全数字化视频和声音发送接口,可以发送未压缩的音频及视频信号。随着技术的不断提升,HDMI的传输速率也不断的提升&#…

【力扣每日一题】1572. 矩阵对角线元素的和 8.11打卡

文章目录 题目思路代码 题目 1572. 矩阵对角线元素的和 难度: 简单 描述: 给你一个正方形矩阵 mat,请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 返回合并后的二叉树。 注意…

企业权限管理(十)-用户详情

用户详情 UserController findById方法 Controller RequestMapping("/user") public class UserController {Autowiredprivate IUserService userService;//查询指定id的用户RequestMapping("/findById.do")public ModelAndView findById(String id) thro…

【设计模式——学习笔记】23种设计模式——状态模式State(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入介绍基本介绍登场角色应用场景 案例实现案例一类图实现 案例二:借贷平台源码剖析传统方式实现分析状态修改流程类图实现 案例三:金库警报系统系统的运行逻辑伪代码传统实现方式使用状态模式 类图实现分析问题问题一问题二 总结文章说明…

【广州华锐视点】VR线上教学资源平台提供定制化虚拟现实学习内容

虚拟现实(VR)技术的出现为我们提供了一种全新的在线教学方式。由广州华锐视点开发的VR线上教学资源平台,作为一个综合性的学习工具,正在教育领域迅速发展,并被越来越多的教育机构和学生所接受。那么,VR线上…

TikTok广告投放如何做?2023超全实用干货

目前Tiktok月活用户达到12亿,覆盖150地方,66%用户年龄30以下,流量不容小觑。在部分地区,TikTik广告已经是能够与Facebook与Google广告掰掰手腕的程度了。且目前来说,投放TikTok ads的成本比FB ads要低一些,…

搭建Web服务器并用cpolar发布至公网访问

本地电脑搭建Web服务器并用cpolar发布至公网访问 文章目录 本地电脑搭建Web服务器并用cpolar发布至公网访问前言1. 首先在电脑安装PHPStudy、WordPress、cpolar2. 安装cpolar,进入Web-UI界面3. 安装wordpress4. 进入wordpress网页安装程序5. 利用cpolar建立的内网穿…

SpringBoot集成KoTime

koTime是一个开源免费的springboot项目性能分析工具&#xff0c;通过追踪方法调用链路以及对应的运行时长快速定位性能瓶颈&#xff0c;除此之外&#xff0c;代码热更新、异常检测都可以有&#xff01; 一.添加KoTime依赖&#xff1a; <dependency><groupId>cn.l…

【直接收藏】前端 VUE 高阶面试题(二)

44.vuex的数据丢失知道吗 怎么解决 原理&#xff1a;可以利用缓存&#xff0c;将vuex中的state&#xff0c;在缓存中备份一下&#xff0c;当状态发生改变时&#xff0c;同步缓存的的备份。同时当刷新时&#xff0c;去缓存中的备份&#xff0c;给state赋值 实际开发中我们一般…

【机器学习6】数据预处理(三)——处理类别数据(有序数据和标称数据)

处理类别数据 &#x1f331;简要理解处理类别数据的重要性☘️类别数据的分类☘️方便研究——用pandas创建包含多种特征的数据集&#x1f340;映射有序特征&#x1f340;标称特征标签编码&#x1f340;标称特征的独热编码&#x1f331;独热编码的优缺点 &#x1f331;简要理解…

NeuralNLP-NeuralClassifier的使用记录(二),训练预测自己的【中文文本多分类】

NeuralNLP-NeuralClassifier的使用记录&#xff0c;训练预测自己的【中文文本多分类】 数据准备&#xff1a; ​ 与英文的训练预测一致&#xff0c;都使用相同的数据格式&#xff0c;将数据通过代码处理为JSON格式&#xff0c;以下是我使用的一种&#xff0c;不同的原数据情况…

【Visual Studio Code】--- Win11 安装 VS Code 超详细

Win11 安装 VS Code 超详细 概述一、下载 Vscode二、安装 Vscode 概述 一个好的文章能够帮助开发者完成更便捷、更快速的开发。书山有路勤为径&#xff0c;学海无涯苦作舟。我是秋知叶i、期望每一个阅读了我的文章的开发者都能够有所成长。 一、下载 Vscode Vscode官网 二、…