Nginx 上没有尾部斜线的虚荣 URL
Vanity URLs without trailing slashes on Nginx
在@jon-lin 的帮助下,我们找到了在 Apache 上删除尾部斜杠的方法 ();现在,当我们计划 运行 我们的网站在 Nginx 上时,我们也想这样做。我们尝试了在 Whosebug 和其他地方找到的几个建议,但都导致无限循环(可能是因为浏览器试图将斜杠放回原处)。我们当前的配置(我们的三个尝试 -- rewrite ^/(.*)/$ https://www.example.com/ permanent;
rewrite ^/(.*)/$ https://www.example.com/;
和 rewrite ^/(.*)/$ / 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/ permanent;
#rewrite ^/(.*)/$ https://www.example.com/;
#rewrite ^/(.*)/$ / 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 的尾部斜杠;我们通过将以下内容添加到 Apache 的 httpd.conf:
来实现这一点
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ //
然后,重写 /profiles/
中的所有条目是这样完成的:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /profiles/ [NC,L]
如果您不再使用 /profiles/ 目录,这应该有效:
server {
...
root /var/www/example.com/html;
index index.php index.html index.htm;
location / {
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*[^/])$ /;
}
location ~ \.php$ { ... }
}
在上面的配置中,我们避免了 try_files
上的 $uri/
元素,因为它会触发重定向,将尾随 /
添加到当前 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/;
}
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$ permanent; }
}
它是无斜杠和无扩展名的混合体php,您的个人资料会有所调整。
将@richard-smith 在他的回答中的第一个选项与 "evil" if
相结合,我们成功了:
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /profiles/ break;
}
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*[^/])$ /;
}
现在所有尾部斜杠都消失了,example.com/profiles/profile/
中的配置文件被重写为 example.com/profile
在@jon-lin 的帮助下,我们找到了在 Apache 上删除尾部斜杠的方法 (rewrite ^/(.*)/$ https://www.example.com/ permanent;
rewrite ^/(.*)/$ https://www.example.com/;
和 rewrite ^/(.*)/$ / 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/ permanent;
#rewrite ^/(.*)/$ https://www.example.com/;
#rewrite ^/(.*)/$ / 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 的尾部斜杠;我们通过将以下内容添加到 Apache 的 httpd.conf:
来实现这一点DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ //
然后,重写 /profiles/
中的所有条目是这样完成的:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /profiles/ [NC,L]
如果您不再使用 /profiles/ 目录,这应该有效:
server {
...
root /var/www/example.com/html;
index index.php index.html index.htm;
location / {
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*[^/])$ /;
}
location ~ \.php$ { ... }
}
在上面的配置中,我们避免了 try_files
上的 $uri/
元素,因为它会触发重定向,将尾随 /
添加到当前 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/;
}
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$ permanent; }
}
它是无斜杠和无扩展名的混合体php,您的个人资料会有所调整。
将@richard-smith 在他的回答中的第一个选项与 "evil" if
相结合,我们成功了:
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /profiles/ break;
}
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*[^/])$ /;
}
现在所有尾部斜杠都消失了,example.com/profiles/profile/
中的配置文件被重写为 example.com/profile