Search code examples
.htaccessnginxmod-rewriteurl-rewriting

URL with Rewrite in Nginx


I want the URLs to look clean and nice with rewrite. I was able to do this while using Apache, but I installed Nginx on the server. So I don't use .htaccess.

While using Apache, I was using it like this:

<IfModule mod_rewrite.c> 
    SetEnv HTTP_MOD_REWRITE On
    RewriteEngine on 
    RewriteBase / 
    RewriteCond %{REQUEST_URI} !\.php$ [NC] 
    RewriteCond %{REQUEST_URI} [^/]$ 
    RewriteRule ^(.*)$ $1.php [L] 
    RewriteCond %{REQUEST_FILENAME} -d [OR] 
    RewriteCond %{REQUEST_FILENAME} -f [OR] 
    RewriteCond %{REQUEST_FILENAME} -l
    RewriteCond %{REQUEST_URI} !.(css|gif|ico|jpg|js|png|swf|txt)$ 
    RewriteRule ^ - [L] 
     RewriteRule ^([^/]+)/([^/]+)?$ index.php?cmd=$1&scd=$2 [L,QSA] 
    RewriteRule ^([^/]+)/?$ index.php?cmd=$1 [L,QSA]
</IfModule>

Example this URL looked like this:

https://example.com/item/1234/bund123

Without mod_rewrite:

https://example.com/index.php?item?id=1234&unt=bund123

I tried to do this Nginx but got 404 error. What could be the reason for this?

server {

    listen *:80;
        listen [::]:80;
        listen *:443 ssl http2;
        server_name example.com www.example.com;
        root   /var/www/example.com/web/;

        rewrite ^([^/]+)/([^/]+)?$ /index.php?cmd=$1&scd=$2 last;
        rewrite ^([^/]+)?$ /index.php?cmd=$1 last;
 
    ....
}

Where am I doing wrong?


Solution

  • Details about the 404 error can be found in the Nginx error log. Presumably, index.php does not exist.

    Rewrite rules can be quickly tested with redirect and Curl:

    # /item/cmd/scd
    rewrite ^/item/([^/]+)/([^/]+) /index.php?cmd=$1&scd=$2 redirect;
    
    # /item/cmd
    rewrite ^/item/([^/]+)         /index.php?cmd=$1        redirect;
    
    $ curl -I https://example.com/item/CMD/SCD
    HTTP/1.1 302 Moved Temporarily
    Location: https://example.com/index.php?cmd=CMD&scd=SCD
    
    $ curl -I https://example.com/item/CMD
    HTTP/1.1 302 Moved Temporarily
    Location: https://example.com/index.php?cmd=CMD
    

    When the rewrites are working properly, change redirect to break:

    rewrite ^/item/([^/]+)/([^/]+) /index.php?cmd=$1&scd=$2 break;
    rewrite ^/item/([^/]+)         /index.php?cmd=$1        break;