NGINX try_files 名称作为 $uri 中的最后一个单词

Posted

技术标签:

【中文标题】NGINX try_files 名称作为 $uri 中的最后一个单词【英文标题】:NGINX try_files with name as the last word in the $uri 【发布时间】:2021-02-20 19:32:52 【问题描述】:

我的服务器上有一个 nginx,我试图让它打开文件“/config/www/pp1/index.php”,地址为https://example.com/pp1,“/config/www/interpreter/index.html”为https://example.com/interpreter。此外,像https://example.com/interpreter/res/docs 这样的所有东西都应该启动'/config/www/interpreter/res/docs.html'。我做了很多尝试。目前我在 /site-confs 中的默认配置文件如下所示:

server 
        listen 80;
        listen 443 ssl http2;
        server_name kni.mini.pw.edu.pl;

        # Path for SSL config/key/certificate
        ssl_certificate /config/keys/cert.crt;
        ssl_certificate_key /config/keys/cert.key;

        location / 
                proxy_read_timeout    90;
                proxy_connect_timeout 90;
                proxy_redirect        off;
                proxy_pass http://kni_website;
                proxy_set_header      X-Real-IP $remote_addr;
                proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header      Host $host;
        

         location /pp1 
                root /config/www;
                index index.html index.htm index.php;
                try_files $uri $uri/ index.php $uri/index.php /config/www/pp1/index.php index.php; #/index.php?$args =404;
                location ~ \.php$ 
                        fastcgi_split_path_info ^(.+\.php)(/.+)$;
                        # With php5-cgi alone:
                        fastcgi_pass 127.0.0.1:9000;
                        # With php5-fpm:
                        #fastcgi_pass unix:/var/run/php5-fpm.sock;
                        fastcgi_index index.php;
                        include /etc/nginx/fastcgi_params;
                
        
         location /interpreter 
                if ($request_uri ~* "([^/]*$)" ) 
                        set  $last_path_component  $1;
                
                root /config/www;
                index index.html index.htm index.php $last_path_component.html;
                try_files /interpreter/res/$last_path_component.html $uri.html $uri.html $uri $uri/ /index.html index.php /$uri.html  /index.php?$args =404;
                location ~ \.php$ 
                        fastcgi_split_path_info ^(.+\.php)(/.+)$;
                        # With php5-cgi alone:
                        fastcgi_pass 127.0.0.1:9000;
                        # With php5-fpm:
                        #fastcgi_pass unix:/var/run/php5-fpm.sock;
                        fastcgi_index index.php;
                        include /etc/nginx/fastcgi_params;
                
        



server 
        listen 80 default_server;

        listen 443 ssl;

        root /config/www;
        index index.html index.htm index.php;

        server_name _;

        ssl_certificate /config/keys/cert.crt;
        ssl_certificate_key /config/keys/cert.key;

        client_max_body_size 0;

        location / 
                try_files $uri $uri/ /index.html /index.php?$args =404;
        

        location ~ \.php$ 
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                # With php5-cgi alone:
                fastcgi_pass 127.0.0.1:9000;
                # With php5-fpm:
                #fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include /etc/nginx/fastcgi_params;

        

坦率地说,我以为我知道自己在做什么,但是现在我很确定位置块 location /interpreter 根本没有被检查,location /pp1 的内部正在引起一些疯狂的胡言乱语。

请帮助有需要的新手!

【问题讨论】:

【参考方案1】:

主要问题是try_files 将在当前上下文中处理其file 元素,因此您无法在同一语句中处理.html.php URI。详情请见this document。

一种解决方案是使用命名位置将try_files 语句一分为二。首先测试$uri$uri.html$uri/index.html,然后再测试$uri.php$uri/index.php

例如:

root /path/to/root;

location /foo 
    try_files $uri $uri.html $uri/index.html @php;
    location ~* ^(.*)\.php$  return 301 $1; 

location @php 
    try_files $uri.php $uri/index.php =404;
    fastcgi_pass  ...;
    ...

添加了location ~* ^(.*)\.php$ 块以正确处理以.php 结尾的URI。最简单的解决方案是将它们重定向到删除了 .php 的 URI。

【讨论】:

谢谢!它现在可以工作,但是我必须导航到example.com/pp1(末尾有斜杠)-当我导航到example.com/pp1(没有斜杠)时它不起作用有没有像重写这样的方法来解决这个问题? 我的意思是https://example.com/pp1/,我希望它可以从https://example.com/pp1 访问(末尾没有斜线) 奇怪的是curl -I https://kni.mini.pw.edu.pl/pp1 显示它重定向到http。您的问题或我的答案中的配置不应该这样做。此服务器是否终止 SSL 连接? 我在其他人管理的代理后面。我无法访问他/她如何处理 ssl certbots。但是,我的问题与此无关,我确实相信(或者不是吗??)。我希望 uri :https://kni.mini.pw.edu.pl/pp1https://kni.mini.pw.edu.pl/pp1/ 一样处理。第一个总是被视为只是https://kni.mini.pw.edu.pl。问题是否与在 location / 下存在一个带有 wordpress 的 docker 的事实有关? 您还在使用$uri/ 作为try_files 声明中的文件术语之一吗?

以上是关于NGINX try_files 名称作为 $uri 中的最后一个单词的主要内容,如果未能解决你的问题,请参考以下文章

如何缩短这个nginx try_files配置?

Nginx precontent阶段 try_files指令

try_files $uri $uri/ @router

Nginx之try_files指令

解释try_files $uri $uri/ /index.php$is_args$args;

Web架构之Nginx try_files