/ / Марномірні URL-адреси без останньої косої риски на Nginx - nginx, переписати, сліш-косу рису

URL-адреси марнотратства без кінцевих косих слів на Nginx - nginx, перезапису, кінцева коса риска

За допомогою @ jon-lin ми з’ясували, як видалити кінцеві косі риси на Apache (Суєтні URL-адреси без кінцевих скісних рисок на Apache); тепер, коли ми плануємо запускати наш сайт на Nginx, ми "dлюблять робити те саме. Ми спробували кілька пропозицій, які ми знайшли на stackoverflow та інших місцях, але всі вони призводять до нескінченного циклу (можливо, тому, що браузери намагаються повернути похилі риси назад). Наша поточна конфігурація (з трьома нашими спробами - rewrite ^/(.*)/$ https://www.example.com/$1 permanent; rewrite ^/(.*)/$ https://www.example.com/$1; і rewrite ^/(.*)/$ /$1 permanent; - прокоментували) це:

server {
listen 80;
server_name  example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 80;
server_name  www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443;
server_name  example.com;
return 301 https://www.example.com$request_uri;
}

server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name www.example.com;

#rewrite ^/(.*)/$ https://www.example.com/$1 permanent;
#rewrite ^/(.*)/$ https://www.example.com/$1;
#rewrite ^/(.*)/$ /$1 permanent;

root /var/www/example.com/html;
index index.php index.html index.htm;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}

location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}

ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECD$
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
ssl_dhparam /etc/ssl/certs/dhparam.pem;

}

Як це можна зробити?

У нашому конкретному випадку нам потрібно було позбавити всіх URL-адрес кінцевих скісих рисок; ми досягли цього, додавши до httpd.conf Apache:

DirectorySlash Off

RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/

Потім, переписуючи всі записи в /profiles/ було досягнуто за допомогою цього:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /profiles/$1 [NC,L]

Відповіді:

1 для відповіді № 1

Якщо ви більше не використовуєте каталог / profiles /, це має працювати:

server {
...
root /var/www/example.com/html;
index index.php index.html index.htm;

location / {
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*[^/])$ $1/;
}
location ~ .php$ { ... }
}

У наведеній вище конфігурації ми уникаємо $uri/ елемент на try_files оскільки він запускає переспрямування, яке додає кінцевий результат / до поточної URL-адреси.

Якщо вам потрібна конфігурація, подібна до вашої попередньої конфігурації Apache, це має спрацювати:

server {
...
root /var/www/example.com/html;
index index.php index.html index.htm;

location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^(.*[^/])$ /profiles$1/;
}
location ~ .php$ { ... }
}

Як ви можете бачити, $uri/ елемент не завдає шкоди в цій ситуації.

Після ваших коментарів та нещодавнього редагування, ця третя (менш елегантна) конфігурація поєднує функції інших двох і є тісною (але не точною) реалізацією вашої конфігурації Apache:

server {
...
root /var/www/example.com/html;
index index.php index.html index.htm;

location = / { rewrite ^ /index.php; }
location / {
try_files $uri @rewrite;
}
location @rewrite {
if (-d $document_root/profile$uri) { rewrite ^ /profiles$uri/ last; }
if (-d $request_filename) { rewrite ^(.*[^/])$ $uri/ last; }
}
location ~ .php$ { ... }
}

І нарешті, ця версія дещо відхиляється від брифу. Блок виконання php замінено іменованим розташуванням. Але це дозволяє використовувати каскад try_files директиви, усуваючи неприємні if директиви та відкидання index в процесі. Насолоджуйтесь:

server {
...
root /var/www/example.com/html;

location / {
try_files $uri $uri.html $uri/index.html /profiles$uri/index.html @php;
}
location @php {
try_files $uri.php $uri/index.php /profiles$uri/index.php =404;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
location ~ .php$ { rewrite ^(.*).php$ $1 permanent; }
}

Це гібрид PHP без скісних рисок та без розширень, з налаштуваннями ваших профілів.


0 для відповіді № 2

Поєднуючи перший варіант @ richard-smith у своїй відповіді тут із "злом" if, ми змусили це працювати:

    location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /profiles$1/ break;
}
try_files $uri @rewrite;
}

location @rewrite {
rewrite ^(.*[^/])$ $1/;
}

Тепер усі кінцеві скісні риски зникли, а профілі в них example.com/profiles/profile/ переписуються на example.com/profile