nginx下try-files说明

root、alias 与 try_files 的配置与应用。

root 与 alias 的区别

root 与 alias 的区别主要在于 Nginx 如何解释 location 后面的路径的 URI,这会使两者分别以不同的方式将请求映射到服务器文件上。具体来看:

root 的处理结果是:root 路径+location 路径
alias 的处理结果是:使用 alias 路径替换 location 路径
例如,如下的 Nginx 配置:

1
2
3
4
5
6
7
server {
listen 9001;
server_name localhost;
location /hello {
root /usr/local/var/www/;
}
}

在请求 http://localhost:9001/hello/时,服务器返回的路径地址应该是/usr/local/var/www/hello/index.html

当使用 alias 时:

1
2
3
4
5
6
7
server {
listen 9001;
server_name localhost;
location /hello {
alias /usr/local/var/www/;
}
}

在请求 http://localhost:9001/hello/时,服务器返回的路径地址应该是/usr/local/var/www/index.html(用 alias 后面的路径将请求的 location 的地址 hello 替换掉)

另外,要注意的是,alias 路径后面必须使用/结束,否则无法匹配正确的路径,而 root 后则可有可无。所以建议都加上/,反之出错

try_files
接触到 try_files,是在对 vue-router 进行 History 模式进行配置时,官网给出的例子中使用到了 try_files:

1
2
3
location / {
try_files $uri $uri/ /index.html;
}

try_files 的作用就是在匹配 location 的路径时,如果没有匹配到对应的路径的话,提供一个回退的方案,在上面的例子中:$uri就代表匹配到的路径。例如我们访问/demo时,$uri 就是 demo

try_files 的最后一个参数是回退方案,前两个参数的意思是,保证如果能够匹配到路径的话访问匹配到的路径,例如访问/demo 时,如果根路径下没有 demo 目录,就会访问 index.html

要注意到的是,/index.html 的服务器路径,会到 root 路径下去寻找,上面的例子中,没有 root 选项,那么就会到 Nginx 的默认根路径下去寻找 index.html,如果设置了 root: a,那么就会到服务器的/a/index.html 路径下去匹配

在非根路径下使用 try_files
当我们希望在/test 路径下部署一个路由使用 History 的 Vue 应用,那么可以使用如下的 Nginx 配置:

1
2
3
4
5
6
7
8
9
server {
listen 9001;
server_name localhost;
location /test {
root /usr/local/var/www/hello/;
index index.html;
try_files $uri $uri/ /test/index.html;
}
}

这个时候:

非/test 路径下的请求,不会收到上面的配置的影响
当访问/test 时,会使用 root 的匹配规则,到服务器/usr/local/var/www/hello/test 路径下寻找 index.html 文件
当访问/test/demo1 时,会使用 try_files 的匹配规则,到 root 路径下去寻找最后一个参数/test/index.html 的回退方案,也就是说去/usr/local/var/www/hello/test 路径下寻找 index.html 文件
除了 Nginx 的配置外,Vue 应用本身还需要配置两处:

(1)vue-router 实例化时指定 history 模式,并添加 base 参数:

1
2
3
4
5
const router = new Router({
routes,
mode: 'history',
base: '/test'
});

(2)静态资源的目录 publicPath 设置为相对路径(否则回去绝对路径下寻找 JS 等静态资源)

1
2
3
{
assetsPublicPath: './'
}

参考

Nginx 的 location、root、alias 指令用法和区别@腾讯云
HTML5 History 模式@vue-router

APP优雅进行SSL证书校验——(一)服务器篇

https://zhuanlan.zhihu.com/p/36628482

生成公钥 pin

https://www.ssllabs.com/ssltest/analyze.html

公钥和证书 pin 介绍

https://m.freebuf.com/articles/endpoint/341407.html

https://medium.com/@Dranko/certificate-pinning-your-android-and-ios-apps-6506972ecb37

证书转换

1
2
3
4
5
6
7
8
// crt -> cer
openssl x509 -in 2023.jin.com.crt -out 2023.jin.com.cer -outform der
openssl s_client -connect pre-service.jfzfund.com:443 </dev/null 2>/dev/null | openssl x509 -outform DER > myWebsite.cer

// cer -> pem
openssl x509 -in dnufzfj0.kecezfj -pubkey -noout > dnufzfj0.pem
// 公钥文件
openssl x509 -inform der -in dnufzfj0.cer -out certificate.pem

通过 chrome 也可以导出.cer 格式证书

通过linux进行文件过滤

先通过 find 命令查找文件,然后对文件中内容,按照关键字进行过滤

1
find /mnt/pc-html/ -maxdepth 1 -name 'vpcspider01_data_config_*' -exec grep -Eonl 'c-.html' {} \;

通过linux进行文件过滤

需求

过滤某文件中,特定行的产品 id,如下所示:

1
2
3
4
5
6
7
2023-09-06 17:24:25.440: [26520] request start, url:/collectionsearch start time:1693992265440ms
2023-09-06 17:24:25.431: [26572] html local file handle error [Error: ENOENT: no such file or directory, stat '/mnt/pc-html/simu/p-22229T4Y.html'] {
errno: -2,
code: 'ENOENT',
syscall: 'stat',
path: '/mnt/pc-html/simu/p-22229T4Y.html'
}

上述中,通过关键字“ENOENT: no such file or directory”,筛选出“p-22229T4Y”这个产品 id

实现

less 命令

less 可以对文件进行分页展示,当文件特别大时,特别有用。通过上下箭头进行翻页

grep 命令

根据关键字筛选某一行。其中,-E 参数表示通过正则匹配,-o 参数表示只输出配置的内容

cut 命令

通过 cut 命令来截取字符串,-c 参数表示通过字符分割。如下示例中,表示从 130 字符开始,截取到行尾

rev 命令

对字符串进行反转

uniq 命令

对字符串进行去重

awk 命令

对字符串的前后加上双引号。注意引号需要转义且需要通过双引号包裹

结果

组合上述命令,最终完整命令如下:

1
less /data/pm2/logs/test-pc-out.log | grep -Eo 'ENOENT: no such file or directory.*' | cut -c 130- | rev | cut -c 10- | rev | uniq | awk '{print "\""$0"\","}' | less

结果为

1
p-22229T4Y

redis命令集合

  1. 通过 monitor,过滤某个 key
1
redis-cli -h r.redis.rds.aliyuncs.com  monitor | grep -i 'indexCodes'

hexo升级到高版本

  1. 根目录 package.json 中 hexo 指向最新版本

    1
    2
    3
    "hexo": "^5.0.0",
    改为
    "hexo": "^6.3.0",
  2. 主题包升级
    themes/icarus 更新为最新版本

  3. 替换底部备案
    文件 themes/icarus/layout/common/footer.jsx 中,修改如下:

1
2
3
4
5
6
7
8
9
&nbsp;&nbsp;<span>www.kch8.top</span>
&nbsp;&nbsp;
<a
href="https://beian.miit.gov.cn"
target="_blank"
rel="noopener"
>
粤ICP备16099065号-1
</a>

http通过range下载文件,错误net::ERR_CONTENT_LENGTH_MISMATCH

代理缓存

首先,查看代理的缓存是否过小;如果过小, nginx 的 http 节点,可以设置后为

1
2
3
proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 128k;

Range 转发

Nginx 向后端服务器请求的时候是不会把 Range 参数加上的,而是会去请求整个文件,比方说有一个 1G 的文件,每次请求 1M,Nginx 会在每次请求的时候去后端请求一个完整的 1G 文件,然后取出其中的 1M 发给客户端,这个时候中间的流量会暴增,导致整个服务器宕机。

1
2
3
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_no_cache $http_range $http_if_range;

react中usestate说明

在 react 开发中,通常用usestate来存储应用的状态,如:

1
2
3
4
const [count, setCount] = React.useState(0)
setCount(count + 1)
console.log('count:', count)
// 输出为0

输出结果为:

1
count:0

当上述设置状态后,去取状态得到的值是 0,而不是 1,这是因为 state 是异步执行且下次渲染时才会生效,当时的设置缓存到队列中

可以通过回调的方式,获取最新的值

1
2
3
4
setCount(count => {
// 完成相关的操作
return count + 1
})