Redirect 在nginx中将/foo.html重定向到/foo,而不是/to/index

Redirect 在nginx中将/foo.html重定向到/foo,而不是/to/index,redirect,nginx,Redirect,Nginx,我在磁盘上的文件有扩展名:index.html,a.html。我想请求http://example.com/a加载/var/www/a.html和http://example.com/加载/var/www/index.html。我希望任何其他url重定向到规范url,因此http://example.com/a.html应重定向到http://example.com/a 我的配置如下所示: rewrite ^(/.+)\.html$ $scheme://$host$1 permanent; lo

我在磁盘上的文件有扩展名:
index.html
a.html
。我想请求
http://example.com/a
加载
/var/www/a.html
http://example.com/
加载
/var/www/index.html
。我希望任何其他url重定向到规范url,因此
http://example.com/a.html
应重定向到
http://example.com/a

我的配置如下所示:

rewrite ^(/.+)\.html$ $scheme://$host$1 permanent;
location / {
    root   /var/www;
    try_files $uri.html $uri $uri/ =404;
}
这会将
/a.html
重定向到
/a
,并成功从磁盘加载
a.html

$ curl -D- -s http://www.jefftk.com/food.html | grep ^Location
Location: http://www.jefftk.com/food
$ curl -s http://www.jefftk.com/food | grep ^Location
但它会将
/
发送到
/索引

$ curl -s -D- http://www.jefftk.com/pictures/ | grep ^Location
Location: http://www.jefftk.com/pictures/index
$ curl -s -D- http://www.jefftk.com | grep ^Location
Location: http://www.jefftk.com/index
$ curl -D- -s http://www.jefftk.com/food.html | grep ^Location
$ curl -D- -s http://www.jefftk.com/food | grep ^Location
$ curl -D- -s http://www.jefftk.com/ | grep ^Location
$ curl -D- -s http://www.jefftk.com/pictures/ | grep ^Location
如果删除重写规则,它将停止从
/a.html
重定向到
/a
,但也会停止将
/
发送到
/index

$ curl -s -D- http://www.jefftk.com/pictures/ | grep ^Location
Location: http://www.jefftk.com/pictures/index
$ curl -s -D- http://www.jefftk.com | grep ^Location
Location: http://www.jefftk.com/index
$ curl -D- -s http://www.jefftk.com/food.html | grep ^Location
$ curl -D- -s http://www.jefftk.com/food | grep ^Location
$ curl -D- -s http://www.jefftk.com/ | grep ^Location
$ curl -D- -s http://www.jefftk.com/pictures/ | grep ^Location

为什么会发生这种情况?我可以同时使用nginx实现我想要的两个功能吗(没有
.html
扩展,url中没有
索引?

我想你的重写规则可能是反向的。可能只是这样(无重写规则):

编辑版本:

对不起,我没有完全理解你的描述。我重读了几遍,并对此进行了测试,它可能接近于您希望执行的操作:

location = / {
    try_files /index.html =404;
}

location = /index {
    return 301 $scheme://$host;
}

location ~* \.html$ {
    rewrite ^(.+)\.html$ $scheme://$host$1 permanent;
}

location / {
    try_files $uri.html $uri/ @backend;
}

location @backend {
    # rewrite or do whatever is default for your setup
    rewrite ^ /index.html last;
    // or return 404;
}
代码示例(修订版3):

我希望第三次是一种魅力。也许这能解决你的问题

# example.com/index gets redirected to example.com/

location ~* ^(.*)/index$ {
    return 301 $scheme://$host$1/;
}

# example.com/foo/ loads example.com/foo/index.html

location ~* ^(.*)/$ {
    try_files $1/index.html @backend;
}

# example.com/a.html gets redirected to example.com/a

location ~* \.html$ {
    rewrite ^(.+)\.html$ $scheme://$host$1 permanent;
}

# anything else not processed by the above rules:
# * example.com/a will load example.com/a.html
# * or if that fails, example.com/a/index.html

location / {
    try_files $uri.html $uri/index.html @backend;
}

# default handler
# * return error or redirect to base index.html page, etc.

location @backend {
    return 404;
}

你在找这样的东西吗:

location / {
    try_files $uri.html $uri/index.html =404;
}

基本上,这将首先尝试
a.html
文件,如果失败,它将尝试
index.html
,最后显示
404
。另外,编辑
vhost
文件后,请记住
重新启动nginx

这不会重定向
http://example.com/file.html
http://example.com/file
。很抱歉,我没有完全理解您的问题,但已重新阅读并测试了一些新规则。我已经修改了上面的代码以包含其他位置。这也不起作用:虽然/没有重定向到/index,/foo仍然重定向到/foo/indexOK,但我已经更新了代码示例并发布了上面编辑的修订(#3)。这样行吗?