Nginx redirect loop, удалите index.php из url

Мне нужны любые запросы типа http://example.com/whatever/index.php, чтобы сделать 301 перенаправление на http://example.com/whatever/.

Я попробовал добавить:

rewrite ^(.*/)index.php$ $1 permanent;

location / {
    index  index.php;
}

Проблема здесь: этот переписать запускается на корневом URL-адресе, что вызывает бесконечный цикл переадресации.

Edit:

Мне нужно общее решение

http://example.com/ должен обслуживать файл webroot/index.php

http://example.com/index.php, если 301 перенаправить на http://example.com/

http://example.com/a/index.php должен 301 перенаправить на http://example.com/a/

http://example.com/a/ должен обслуживать index.php script at webroot/a/index.php

В принципе, я никогда не хочу показывать "index.php" в адресной строке. У меня есть старые обратные ссылки, которые мне нужно перенаправить на канонический URL.

Ответы

Ответ 1

Отличный вопрос, с решением похожий на другой, на который я недавно ответил на ServerFault, хотя он намного проще здесь, и вы точно знаете, что вам нужно.

То, что вы хотите здесь, - это выполнить только перенаправление, когда пользователь явно запрашивает /index.php, но никогда не перенаправляет ни один из внутренних запросов, которые в конечном итоге обслуживаются фактическим index.php script, как определено в index.

Это должно сделать именно это, избегая циклов:

server {
    index index.php;

    if ($request_uri ~* "^(.*/)index\.php$") {
        return 301 $1;
    }

    location / {

        # ...
    }
}

Ответ 2

Попробуйте

location ~ /*/index.php {
    rewrite ^/(.*)/(.*) http://www.votre_domaine.com/$1 permanent;
}
location /index.php {
    return 301 http://www.example.com/;
}

Ответ 3

Сохраните первую косую черту:

rewrite ^/(. +)/index.php$ $scheme://$1/ permanent;

Ответ 4

Try

location = /whatever/index.php {
    return 301 $scheme://www.example.com/whatever/;
}

Другим преимуществом такого решения является то, что nginx выполняет возврат быстрее, чем переписывает.