nginx: rewrite a LOT (2000+) of urls with paramete

2019-01-20 16:50发布

问题:

I have to migrate a lot of URLs with params, which look like that:

/somepath/somearticle.html?p1=v1&p2=v2 --> /some-other-path-a

and also the same URL without params:

/somepath/somearticle.html --> /some-other-path-b

The tricky part is that the two destination URLs are totally different pages in the new system, whereas in the old system the params just indicated which tab to open by default.

I tried different rewrite rules, but came to the conclusion that parameters are not considered by nginx rewrites. I found a way using location directives, but having 2000+ location directives just feels wrong.

Does anybody know an elegant way how to get this done? It may be worth noting that beside those 2000+ redirects, I have another 200.000(!) redirects. They already work, because they're rather simple. So what I want to emphasize is that performance should be key!

回答1:

You cannot match the query string (anything from the ? onwards) in location and rewrite expressions, as it is not part of the normalized URI. See this document for details.

The entire URI is available in the $request_uri parameter. Using $request_uri may be problematic if the parameters are not sent in a consistent order.


To process many URIs, use a map directive, for example:

map $request_uri $redirect {
    default 0;
    /somepath/somearticle.html?p1=v1&p2=v2  /some-other-path-a;
    /somepath/somearticle.html              /some-other-path-b;
}

server {
    ...
    if ($redirect) {
        return 301 $redirect;
    }
    ...
}

You can also use regular expressions in the map, for example, if the URIs also contain optional unmatched parameters. See this document for more.