Making nginx ignore query string parameters

When using nginx as a caching proxy, I found myself needing to ignore particular parameters for both the cache key and the values being passed to the backend. In this particular situation the value I wanted to ignore was ‘uid’. An example URI being:

http://myapplication.fqdn/foo.ext?env=bar&uid=baz&node=qux

or

http://myapplication.fqdn/foo.ext?uid=bar

To ignore this, in the top of my site configuration I put:

proxy_cache_key         "$scheme$host$uri$is_args$args";

in the server stanza:

if ($args ~ (.*?)(?:^|(&))uid=[^&]*(?:(\2.*)|&(.*))?) {
    set $args $1$3$4;
}
if ($args ~ (^w)) {
    set $args ?$args;
}

and the location stanza:

proxy_pass              http://appservers$uri$args;

So now my backend servers see:

GET /foo.ext?env=bar&node=qux

or

GET /bar.ext

and seldom few hits get through to there anyway, as the cache key flattens it appropriately.

Easy.

EDIT: The ‘easy’ bit is a lie, it seems. Thanks to @davidgl for pulling me out of regex hell. Several revisions here helped by him.

4 Replies to “Making nginx ignore query string parameters”

  1. The regexp is broken. The backslash (back reference) befor the digit 2 is lost.

    if ($args ~ (.*?)(?:^|(&))uid=[^&]*(?:(2.*)|&(.*))?) {

    regards
    ralph

  2. I am trying to cache query string, but no luck any tip ?

    So far I tried proxy_cache_key with different $args when ever my url pass from the string. it only cache one css file.

    Advance Thanks
    Thanks!

    1. Hey Sam,

      Do you mean you’re trying to include the query string *in* the cache key, or you’re trying to exclude it?

      That is, do you want files:

      foo.css?bar
      foo.css?baz

      to be the same, or each individually cached?

Leave a Reply

Your email address will not be published. Required fields are marked *