nginx - rewriting index.php?hello=x to index/hello/x

南楼画角 提交于 2021-02-05 11:52:31

问题


How can I rewrite index.php?question=x to index/question/x using nginx

and

make index.php?question=x return 404 not found (if possible)

and

completely remove .php file extension from URLs

I'm sure all of this has been covered somewhere but I have trouble understanding the rewrites on the nginx site.


回答1:


You can't make index.php return a 404 error if index.php actually exists and you want to be rewriting to it.

Both this ...

rewrite ^index/question/(.*)$ /index.php?question=$1 last;

location = /index.php {
    return 404;
}

... and this ...

rewrite ^(.*)/(.*)/(.*)$ /$1.php?$2=$3 last;

location ~* \.php$ {
    return 404;
}

... will return 404 errors for every "index/question/x" request. This is because the rewrite mechanism is simply a case of the webserver issuing a background request for the rewritten resource.

So "index/question/x" will generate an "index.php?question=x" background request which will hit the location saying that a "404" error should be returned.

If you want to completely get rid of index.php from your urls, you need to make your application stop generating index.php links. If you are not creating such links, they will go away from use.

You could do something between Nginx and your application to quicken the process though.

  1. First, change your application to always generate "index/question/x" links
  2. Add a dummy tag to "/index.php?question=x" rewrite in Nginx so that your application knows this is a background request originating from Nginx.
  3. Set your application to test whether this dummy tag is present, or not, for any "/index.php?question=x" type request it gets. If present, serve request, if not, redirect to a "index/question/x" url.
  4. We also need a dummy key in Nginx ("apptag") to recognise these types of links and which allows us to deal with these in their own location without having our rewrites mess up other legitimate links.

In Nignx:

# Any request uri starting with "/app_tag/" is given the treatment
location ~* ^/app_tag/ {
    rewrite ^/app_tag/(.+)/(.+)/(.+)$ /$1.php?$2=$3&dummy_tag last;
    rewrite ^/app_tag/(.+)/?$ /$1.php?dummy_tag last;
}
location ~* \.php$ {
    #proxy_pass/fastcgi_pass etc
}

In your application:

$dummy_tag = "dummy_tag";
$app_tag = "app_tag";
$test_dummy_tag = preg_match($dummy_tag, $_SERVER['REQUEST_URI']) ? TRUE : FALSE;
if (!$test_dummy_base_tag) {
    // Dummy tag not present so we need redirect user
    $pattern_all = '~^/(.+)\.php\?(.+)=(.+)~si';
    $test_pattern_all = preg_match($pattern_all, $_SERVER['REQUEST_URI']) ? TRUE : FALSE;
    if ($test_pattern_all) {
        preg_match($pattern_all, $_SERVER['REQUEST_URI'], $matches);
        $pattern_new = "/apptag/" . $matches[1] . "/" . $matches[2] . "/" . $matches[3] . "/";
    } else {
        $pattern = '~^/(.+)\.php$~si';
        $test_pattern = preg_match($pattern, $_SERVER['REQUEST_URI']) ? TRUE : FALSE;
        if ($test_pattern) {
            preg_match($pattern, $_SERVER['REQUEST_URI'], $matches);
            $pattern_new = "/" . $app_tag . "/" . $matches[1] . "/";
        }
    }
    header('HTTP/1.1 301 Moved Permanently');
    header (location: "http://" . $_SERVER['HTTP_HOST'] . $pattern_new);
}

You can modify/extend this as required.




回答2:


This should rewrite index/question/X to index.php?question=X and return a 404 for index.php However this isn't guaranteed to remove .php

rewrite ^index/question/(.*)$ /index.php?question=$1 last;

location = /index.php {
  return 404;
}

You could also try a more generic solution like

rewrite ^(.*)/(.*)/(.*)$ /$1.php?$2=$3 last;

location ~* \.php$ {
  return 404;
}

This will redirect A/B/C to A.php?B=C and return a 404 for anything ending in .php

Note: You'd probably want to wrap the rewrite inside a location block too and use try_files to make sure this doesn't end up rewriting requests for images, etc too.



来源:https://stackoverflow.com/questions/7745510/nginx-rewriting-index-phphello-x-to-index-hello-x

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!