Closed cdeutsch closed 9 years ago
@crdeutsch - This isn't a bad idea, but I feel like this could be resolved with a simple middleware like this:
app.use(function(req, res, next) {
if(req.url.match(autoFingerprintRegex)) {
req.assetFingerprint();
}
next();
});
Will that work? What are your thoughts? Closing this issue for now, but please feel free to post back here.
That would almost work.
The issue with doing it that way is you'd be calling req.assetFingerprint()
on every request and I don't see any logic that would stop it from re-building the cache strategy for the file every time.
The middleware would have to be placed after the node-static-asset middleware to work properly. If your server gets a fingerprinted URL (i.e. /js/jquery.min.js?v=3dd-983jk2a
), and the URL has been previously registered, static-asset will handle the request with the 304 response (if the client sent If-None-Match
or Last-Modified-Since
headers)... no computations or hitting the disk is necessary unless the client doesn't have the asset at all. In this case, Express's static middleware will handle the request. Either way, the response will also contain the Etag and strong caching headers to encourage the client not to request the fingerprinted asset again.
The client is only going to request the fingerprinted URLs because those are the URLs that appear in the views. Suppose process A serves a view that calls assetFingerprint
. As in a single-threaded environment, the client will request the document using the fingerprinted URL, and the server will respond with either 200 or 304 along with the strong and weak caching headers. In the case where 304 is returned, no other middleware will be called.
Suppose process B handled the request and process B hasn't served the views yet and registered the fingerprints. In this case, we simply register the fingerprint using the regex. The query string on the end of the request is ignored by Express's static middleware, and the asset is read from disk and served. Now, for that request, the server will respond with 200 (or maybe 304 if the client's If-None-Match
matches the CRC from the file just read from disk), but the weak/strong caching headers will not be added by static-asset on this request. But now both process A and process B have the fingerprint registered for that asset, so a subsequent request for that same asset will likely result in a 200 or 304 along with the strong/weak caching headers, regardless of which client or web browser that submitted the request.
Does that make sense?
Ok, I see what you're saying.
Makes sense.
For now I'll keep using my forked version, but if it becomes a pain to keep in sync with your repo I may revisit it.
OK... wait... I think I see what you mean now. If a client hits the server with a fingerprinted URL and the client does not send any weak caching headers (i.e. If-None-Match
, Last-Modified
, etc.), then the middleware will run. In this case, the response is going to be slow because the file has to be loaded from disk using Express's static middleware... or whatever.
However... for these cases, the default strategy uses a cache to prevent the fingerprint from being re-computed over and over.
OK, cool. Whatever you decide sounds good. This repo doesn't change often, so you're probably all good. :) Thanks for the PR and for the discussion... re-visiting this lib from time to time is a good refresher on how it actually works.
Not sure if you're interested in this but in my scenario I needed to add support for multiple instances of a web server running.
Without this only the first thread will initially make the
req.assetFingerprint()
calls in your view which populates our collection offingerprints
. The other threads will not have thefingerprints
collection populated but will likely handle one or more requests for the assets and when they do your strategy will not be applied.Feel free to use it or not and thanks for creating this package. :)