Search code examples
node.jsexpressiiscachingurl-rewrite-module

IISNode unexpectedly returning the same result for a GET request with query parameters


I have an express.js application that is hosted by IIS, using IISNode and a URL ReWrite rules as per the documented best practice.

There exists an endpoint /foo?q=1 that takes a query parameter and for every GET request will return a HTML body that contains a slightly different value (imagine a HTML body that contains a timestamp that updates for each request.)

Putting aside the potential 'bad practice' of a HTTP GET varying by something 'outside of the client's control' for one moment, I've been tearing my hair out trying to work out why this endpoint is not returning a different result for each request, in fact, it works fine, unique responses, for the first 3-4 request, then suddenly starts returning the exact same response for every future request. (The only thing that changes this behaviour is if I change the value of the query parameter, in which case, for that particular url&query combination it works for 3-4 requests, then 'locks in' on the last response.)

To further confuse & complicate, this only appears to happen on a Windows 2019 server, not a Windows 2012 server.


Solution

  • After much confusion this turned out to be a relatively simple issue with IIS output caching.

    Fundamentally, if you have output caching enabled (user or kernal mode) and a rule configured for *.js and your HTTP Requests have query parameters then output caching will cache all of the requests going to your node application.

    This appears to be a result of the URL Rewrite behaviour that means that the Output Caching appears to be 'acting' on the node entry point (commonly app.js).

    In effect, and particularly baffling until you understand the underlying reason, this means that every request that is made to your node application is subject to intermittent caching!

    Additionally, it appears that if you wanted to only selectively cache *.css or *.jpeg etc. files coming from your node application you cannot do this (as all URLS appear to be treated as .js that is the only rule that ever applies and is always blanket.)

    My hope is this saves some other poor soul from getting confused by this 'on the surface' surprising caching behaviour of IIS OutputCaching with IISNode, URL Rewrite and Node.js!