Caching images, CSS and JS resources in Wicket 1.5.3 - performance

I am trying to optimize the performance of a Wicket 1.5.3 application.
I'm trying to get the caching configuration up and running. I've already reviewed "migration to 1.5" papers, the migration guide and samples. I've also ensured that there is a default caching strategy available, and tried to set a custom one.
getResourceSettings().setCachingStrategy(strat);
The app has CSS and JS in a Base-Frame.html header as link and script, and it has a lot of images. I'm currently using something like this:
Image img = new Image("logoutImg") {
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
tag.put("src", baseUrl + "/images/logout.png");
}
};
With that, the HTTP header output is always:
Pragma No-cache
Cache-Control no-cache
for all resources and pages.
I've now implemented some servlet filters, which is a rather brutish method that avoids all previously set Wicket headers.
Could anyone provide a running working example, or some tips for getting this up and running? In particular, something using FilenameWithVersionResourceCachingStrategy would be really helpful, since that seems to be a good solution.

I guess you have to use Wicket's CachingImage class allowing you to set the headers accordingly to the browser

Related

Hot to make visitors of my page automatically see the updated version (prevent caching) [duplicate]

Is there a way I can put some code on my page so when someone visits a site, it clears the browser cache, so they can view the changes?
Languages used: ASP.NET, VB.NET, and of course HTML, CSS, and jQuery.
If this is about .css and .js changes, then one way is "cache busting" by appending something like "_versionNo" to the file name for each release. For example:
script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.
or after the file name:
script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.
You can check this link to see how it could work.
Look into the cache-control and the expires META Tag.
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">
Another common practices is to append constantly-changing strings to the end of the requested files. For instance:
<script type="text/javascript" src="main.js?v=12392823"></script>
Update 2012
This is an old question but I think it needs a more up to date answer because now there is a way to have more control of website caching.
In Offline Web Applications (which is really any HTML5 website) applicationCache.swapCache() can be used to update the cached version of your website without the need for manually reloading the page.
This is a code example from the Beginner's Guide to Using the Application Cache on HTML5 Rocks explaining how to update users to the newest version of your site:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
See also Using the application cache on Mozilla Developer Network for more info.
Update 2016
Things change quickly on the Web.
This question was asked in 2009 and in 2012 I posted an update about a new way to handle the problem described in the question. Another 4 years passed and now it seems that it is already deprecated. Thanks to cgaldiolo for pointing it out in the comments.
Currently, as of July 2016, the HTML Standard, Section 7.9, Offline Web applications includes a deprecation warning:
This feature is in the process of being removed from the Web platform.
(This is a long process that takes many years.) Using any of the
offline Web application features at this time is highly discouraged.
Use service workers instead.
So does Using the application cache on Mozilla Developer Network that I referenced in 2012:
Deprecated This feature has been removed from the Web standards.
Though some browsers may still support it, it is in the process of
being dropped. Do not use it in old or new projects. Pages or Web apps
using it may break at any time.
See also Bug 1204581 - Add a deprecation notice for AppCache if service worker fetch interception is enabled.
Not as such. One method is to send the appropriate headers when delivering content to force the browser to reload:
Making sure a web page is not cached, across all browsers.
If your search for "cache header" or something similar here on SO, you'll find ASP.NET specific examples.
Another, less clean but sometimes only way if you can't control the headers on server side, is adding a random GET parameter to the resource that is being called:
myimage.gif?random=1923849839
I had similiar problem and this is how I solved it:
In index.html file I've added manifest:
<html manifest="cache.manifest">
In <head> section included script updating the cache:
<script type="text/javascript" src="update_cache.js"></script>
In <body> section I've inserted onload function:
<body onload="checkForUpdate()">
In cache.manifest I've put all files I want to cache. It is important now that it works in my case (Apache) just by updating each time the "version" comment. It is also an option to name files with "?ver=001" or something at the end of name but it's not needed. Changing just # version 1.01 triggers cache update event.
CACHE MANIFEST
# version 1.01
style.css
imgs/logo.png
#all other files
It's important to include 1., 2. and 3. points only in index.html. Otherwise
GET http://foo.bar/resource.ext net::ERR_FAILED
occurs because every "child" file tries to cache the page while the page is already cached.
In update_cache.js file I've put this code:
function checkForUpdate()
{
if (window.applicationCache != undefined && window.applicationCache != null)
{
window.applicationCache.addEventListener('updateready', updateApplication);
}
}
function updateApplication(event)
{
if (window.applicationCache.status != 4) return;
window.applicationCache.removeEventListener('updateready', updateApplication);
window.applicationCache.swapCache();
window.location.reload();
}
Now you just change files and in manifest you have to update version comment. Now visiting index.html page will update the cache.
The parts of solution aren't mine but I've found them through internet and put together so that it works.
For static resources right caching would be to use query parameters with value of each deployment or file version. This will have effect of clearing cache after each deployment.
/Content/css/Site.css?version={FileVersionNumber}
Here is ASP.NET MVC example.
<link href="#Url.Content("~/Content/Css/Reset.css")?version=#this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />
Don't forget to update assembly version.
I had a case where I would take photos of clients online and would need to update the div if a photo is changed. Browser was still showing the old photo. So I used the hack of calling a random GET variable, which would be unique every time. Here it is if it could help anybody
<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
EDIT
As pointed out by others, following is much more efficient solution since it will reload images only when they are changed, identifying this change by the file size:
<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
A lot of answers are missing the point - most developers are well aware that turning off the cache is inefficient. However, there are many common circumstances where efficiency is unimportant and default cache behavior is badly broken.
These include nested, iterative script testing (the big one!) and broken third party software workarounds. None of the solutions given here are adequate to address such common scenarios. Most web browsers are far too aggressive caching and provide no sensible means to avoid these problems.
Updating the URL to the following works for me:
/custom.js?id=1
By adding a unique number after ?id= and incrementing it for new changes, users do not have to press CTRL + F5 to refresh the cache. Alternatively, you can append hash or string version of the current time or Epoch after ?id=
Something like ?id=1520606295
<meta http-equiv="pragma" content="no-cache" />
Also see https://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images
Here is the MDSN page on setting caching in ASP.NET.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True
If Response.Cache.VaryByParams("Category") Then
'...
End If
Not sure if that might really help you but that's how caching should work on any browser. When the browser request a file, it should always send a request to the server unless there is a "offline" mode. The server will read some parameters like date modified or etags.
The server will return a 304 error response for NOT MODIFIED and the browser will have to use its cache. If the etag doesn't validate on server side or the modified date is below the current modified date, the server should return the new content with the new modified date or etags or both.
If there is no caching data sent to the browser, I guess the behavior is undetermined, the browser may or may not cache file that don't tell how they are cached. If you set caching parameters in the response it will cache your files correctly and the server then may choose to return a 304 error, or the new content.
This is how it should be done. Using random params or version number in urls is more like a hack than anything.
http://www.checkupdown.com/status/E304.html
http://en.wikipedia.org/wiki/HTTP_ETag
http://www.xpertdeveloper.com/2011/03/last-modified-header-vs-expire-header-vs-etag/
After reading I saw that there is also a expire date. If you have problem, it might be that you have a expire date set up. In other words, when the browser will cache your file, since it has a expiry date, it shouldn't have to request it again before that date. In other words, it will never ask the file to the server and will never receive a 304 not modified. It will simply use the cache until the expiry date is reached or cache is cleared.
So that is my guess, you have some sort of expiry date and you should use last-modified etags or a mix of it all and make sure that there is no expire date.
If people tends to refresh a lot and the file doesn't get changed a lot, then it might be wise to set a big expiry date.
My 2 cents!
I implemented this simple solution that works for me (not yet on production environment):
function verificarNovaVersio() {
var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
$.ajax({
url: "./versio.txt"
, dataType: 'text'
, cache: false
, contentType: false
, processData: false
, type: 'post'
}).done(function(sVersioFitxer) {
console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
location.reload(true);
}
});
}
I've a little file located where the html are:
"versio.txt":
v00.5.0014
This function is called in all of my pages, so when loading it checks if the localStorage's version value is lower than the current version and does a
location.reload(true);
...to force reload from server instead from cache.
(obviously, instead of localStorage you can use cookies or other persistent client storage)
I opted for this solution for its simplicity, because only mantaining a single file "versio.txt" will force the full site to reload.
The queryString method is hard to implement and is also cached (if you change from v1.1 to a previous version will load from cache, then it means that the cache is not flushed, keeping all previous versions at cache).
I'm a little newbie and I'd apreciate your professional check & review to ensure my method is a good approach.
Hope it helps.
In addition to setting Cache-control: no-cache, you should also set the Expires header to -1 if you would like the local copy to be refreshed each time (some versions of IE seem to require this).
See HTTP Cache - check with the server, always sending If-Modified-Since
There is one trick that can be used.The trick is to append a parameter/string to the file name in the script tag and change it when you file changes.
<script src="myfile.js?version=1.0.0"></script>
The browser interprets the whole string as the file path even though what comes after the "?" are parameters. So wat happens now is that next time when you update your file just change the number in the script tag on your website (Example <script src="myfile.js?version=1.0.1"></script>) and each users browser will see the file has changed and grab a new copy.
Force browsers to clear cache or reload correct data? I have tried most of the solutions described in stackoverflow, some work, but after a little while, it does cache eventually and display the previous loaded script or file. Is there another way that would clear the cache (css, js, etc) and actually work on all browsers?
I found so far that specific resources can be reloaded individually if you change the date and time on your files on the server. "Clearing cache" is not as easy as it should be. Instead of clearing cache on my browsers, I realized that "touching" the server files cached will actually change the date and time of the source file cached on the server (Tested on Edge, Chrome and Firefox) and most browsers will automatically download the most current fresh copy of whats on your server (code, graphics any multimedia too). I suggest you just copy the most current scripts on the server and "do the touch thing" solution before your program runs, so it will change the date of all your problem files to a most current date and time, then it downloads a fresh copy to your browser:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
then ... the rest of your program...
It took me some time to resolve this issue (as many browsers act differently to different commands, but they all check time of files and compare to your downloaded copy in your browser, if different date and time, will do the refresh), If you can't go the supposed right way, there is always another usable and better solution to it. Best Regards and happy camping. By the way touch(); or alternatives work in many programming languages inclusive in javascript bash sh php and you can include or call them in html.
For webpack users:-
I added time with chunkhash in my webpack config. This solved my problem of invalidating cache on each deployment. Also we need to take care that index.html/ asset.manifest is not cached both in your CDN or browser. Config of chunk name in webpack config will look like this:-
fileName: [chunkhash]-${Date.now()}.js
or If you are using contenthash then
fileName: [contenthash]-${Date.now()}.js
This is the simple solution I used to solve in one of my applications using PHP.
All JS and CSS files are placed in a folder with version name. Example : "1.0.01"
root\1.0.01\JS
root\1.0.01\CSS
Created a Helper and Defined the version Number there
<?php
function system_version()
{
return '1.0.07';
}
And Linked JS and SCC Files like below
<script src="<?= base_url(); ?>/<?= system_version();?>/js/generators.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="<?= base_url(); ?>/<?= system_version(); ?>/css/view-checklist.css" />
Whenever I make changes to any JS or CSS file, I change the System Verson in Helper and rename the folder and deploy it.
I had the same problem, all i did was change the file names which are linked to my index.html file and then went into the index.html file and updated their names, not the best practice but if it works it works. The browser sees them as new files so they get redownloaded on to the users device.
example:
I want to update a css file, its named styles.css, change it to styless.css
Go into index.html and update , and change it to
in case interested I've found my solution to get browsers refreshing .css and .js in the context of .NET MVC (.net fw 4.8) and the use of bundles.
I wanted to make browsers refresh cached files only after a new assembly is deployed.
Buinding on Paulius Zaliaduonis response, my solution is as follows:
store your application base url in the web config app settings (the HttpContext is not yet available at runtime during the RegisterBundle...), then make this parameter changing according to the configuration (debug, staging, release...) by the xml transform
In BundleConfig RegisterBundles get the assembly version by the means of reflection, and...
...change the default tag format of both styles and scripts so that the bundling system generates link and script tags appending a query string parameter on them.
Here is the code
public static void RegisterBundles(BundleCollection bundles)
{
string baseUrl = system.Configuration.ConfigurationManager.AppSettings["by.app.base.url"].ToString();
string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
Styles.DefaultTagFormat = $"<link href='{baseUrl}{{0}}?v={assemblyVersion}' rel='stylesheet'/>";
Scripts.DefaultTagFormat = $"<script src='{baseUrl}{{0}}?v={assemblyVersion}'></script>";
}
You'll get tags like
<script src="https://example.org/myscriptfilepath/script.js?v={myassemblyversion}"></script>
you just need to remember to to build a new version before deploying.
Ciao
2023 onward
At the time of writing, many web browsers support the Clear-Site-Data HTTP header [MDN reference]. To instruct the client web browser to clear the cache for the website domain and subdomains, set the following header in the HTTP response from the server:
Clear-Site-Data: "cache"
Alternatively, the following header may be better supported across browsers, but it clears other website data, such as localStorage and cookies, in addition to the cache.
Clear-Site-Data: "*"
However note that intermediate caches (e.g. a CDN) may not understand or respect this header, so intermediate caches may still respond with previously cached data.
Do you want to clear the cache, or just make sure your current (changed?) page is not cached?
If the latter, it should be as simple as
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

how to selectively disable cache for spring boot (manifest.appcache)

From this question it shows that spring security manages cache for spring boot. From the spring boot documentation it shows how to set cache for resources using:
spring.resources.cache-period= # cache timeouts in headers sent to browser
The cache-period is great for all the predefined static locations for spring boot (i.e. /css**, /js/**, /images/**) but I'm also generating a manifest.appcache for offline downloading of my static assets and due to all the above spring security/boot sends back cache headers with the manifest.appcache
"method": "GET",
"path": "/manifest.appcache",
"response": {
"X-Application-Context": "application:local,flyway,oracle,kerberos:8080",
"Expires": "Tue, 06 Oct 2015 16:59:39 GMT",
"Cache-Control": "max-age=31556926, must-revalidate",
"status": "304"
}
I'd like to know how to add an exclusion for manifest.appcache. IE and Chrome seem to 'do the right thing' with appcache regardless of my headers, but FF seems to be a little more peculiar in noting when the appcache has changed and I'm thinking my cache headers are screwing it up.
EDIT:
I should add from the source for WebMvcAutoConfiguration it shows how the cache is setup for the resources, I'm just unsure how to selectively disable for my 1 case w/o potentially disrupting the rest of what spring boot sets up in this file.
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/**")) {
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(cachePeriod);
}
if (!registry.hasMappingForPattern("/**")) {
registry.addResourceHandler("/**")
.addResourceLocations(RESOURCE_LOCATIONS)
.setCachePeriod(cachePeriod);
}
}
Based on this answer detailing IE needing "max-age=1, must-revalidate", and through testing on all browsers, setting a properties value of
spring.resources.cache-period=1
will allow the proper http headers to be written which allow the appcache manifest to be handled properly. it's not the solution I hoped for (being able to have a cache-period of 0 with proper headers is what i wanted) but it does make the browser perform properly and utilize the appcache manifest properly.
Again to summarize the solution context - this is for my app that downloads all my assets offline (js/css/html) and serves from appcache.
Thanks for the Q and the A!
We had similar problems: All browsers (Chrome, Safari, IE) but one (FF) didn't cache the manifest files themselves but reloaded it after a change.
However, setting the cache period setting in Spring Boot didn't solve the problem completely. Additionally I didn't want to set cache-control parameters for all files served by the Spring Boot application, but only to disable caching for the manifest.
My solution consists of of two parts:
Provide a "rev" comment in the Manifest file. Though not covered by the W3C spec some browsers seem to want a comment like this to detect changes in the manifest or the referenced (cached) files:
# rev 7
We now change the "rev" parameter in the cache manifest file by a Maven generated unique build number: https://github.com/dukecon/dukecon_html5/commit/b60298f0b856a7e54c97620f278982142e3e1f45).
Disable caching by providing a Filter which adds a header "Cache-Control: no-cache" to exactly the cache.manifest file pattern: https://github.com/dukecon/dukecon_server/commit/dc02f26996cb172df804da007546f439df75126d
In current version (Feb 2016) there is no need to do something in code to change default behavior.
Just do some configuration in your application.properties:
# Enable HTML5 application cache manifest rewriting.
spring.resources.chain.html-application-cache=true
# Enable the Spring Resource Handling chain. Disabled by default unless at least one strategy has been enabled.
spring.resources.chain.enabled=true
# Enable the content Version Strategy.
spring.resources.chain.strategy.content.enabled=true
# Comma-separated list of patterns to apply to the Version Strategy.
spring.resources.chain.strategy.content.paths=/**
# Locations of static resources.
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
That's all. Now Spring will check if your static files was changed and can send smarter responses (If-Modiffied-Since and others) and rewrite your appcache also.
Also, if there are reasons to not use content-based version for some resources - you can use alternate FixedVersion strategy and set version explicitly in your config:
#Enable the fixed Version Strategy.
spring.resources.chain.strategy.fixed.enabled=false
# Comma-separated list of patterns to apply to the Version Strategy.
spring.resources.chain.strategy.fixed.paths=
# Version string to use for the Version Strategy.
spring.resources.chain.strategy.fixed.version=
P.S. Don't forget about Spring Security: it rewrite cache headers and disable caching.
See more in docs

Does jsoup.connect().get() return cached Document?

I use jsoup and following code to get the HTML content of a website Document doc = Jsoup.connect(this.getUrl()).get();.
Does I get a cached version of the website? Is it possible to request a non-cached version? I knew I could set a header request. Something like:
header("Cache-control", "no-cache");
header("Cache-store", "no-store");
But I’m not sure if that works. I just knew that these tags are used for the client browser.
It would be awesome if someone could clarify. Greetings.
Any headers that you correctly (HTTP spec) specify will be sent to target host via java.net.URLConnection.addRequestProperty(String, String). You should get a cached version of the page if server supports this header, end-to-end. jSoup just supplies the headers as the request it made and when I looked through the source, it does not make any explicit effort to cache off the response content.

Why aren't my images caching?

I have an ASP.NET MVC3 application setup. There is a controller that returns back images and I have added the following:
[OutputCache(Duration = 3600, VaryByParam = "id;width", Order = 1000, Location = OutputCacheLocation.Client)]
public ActionResult Get(string id, int width)
{ ... }
But when I check out the HTTP Response on these images they all have headers that say "cache-control: no-cache" and "expires: -1" which means the browser is never caching them.
I'm looking all around and I can't find anything on why the response is telling the browser not to cache them. I even tried working up my own attribute that did:
public class ContentExpiresHeader : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var cache = filterContext.HttpContext.Response.Cache;
cache.SetExpires(DateTime.Now.AddYears(1));
cache.SetCacheability(HttpCacheability.Private);
cache.SetLastModifiedFromFileDependencies();
base.OnResultExecuted(filterContext);
}
}
but that didn't get me anywhere either.
Any help is appreciated.
UPDATE: I'm starting to think this has got to be an IIS setting somewhere that is adding the no-cache and overriding. I can't seem to find anything, though. The only odd thing is that if I take a look at the state of the cache variable after I've called the .Set...() methods the internal variables have not been updated. I would have expected something to change but they're still showing "no-cache".
UPDATE 2: I should add that the return of this method is a:
return File(...);
UPDATE 3: I also found this (http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-3-Controller-for-Serving-Images.aspx) and tried implementing it without any luck. Still getting the no-cache options on the response header for the images.
UPDATE 4: Just had to check server settings... if I bypass my controller and go straight to an image file on the server, then it DOES cache and has the correct caching settings in the response header.
UPDATE 5 (yeah, getting crazy): Created a brand new MVC3 project and just made the one controller and it cached just fine. So I've got something outside the immediate code that is adding this pragma:no-cache stuff and for the life of me I can't figure out what it'd be. =-/
Try changing the cacheability from HttpCachability.Private to HttpCachability.ServerAndPrivate. It should keep the cache-control as private and not suppress e-tags/last modified.
Found the problem! And it's the weirdest thing I've seen in a while.
I am using SocialAuth-net and somewhere during the setup I added the system.webServer module for it and set runAllManagedModulesForAllRequests=true. I thought, "huh, wonder if that's causing it somehow", as I couldn't reproduce the problem outside this particular app. Low and behold, commenting out that section of the config and my images started caching! Hoorah!
But, it gets weirder. I undid my config changes, refreshed and now I'm still getting caching. I can't tell you how many resets of the system I've done with no change but somehow temporarily removing these modules from the pipeline seems to have resolved this problem.
I can track it down to the SocialAuthHttpModule and if I remove it SocialAuth-net still seems to work but caching is restored reliably. Very weird.

Http Modules are called on every request when using mvc/routing module

I am developing a http module that hooks into the FormsAuthentication Module through the Authenticate event.
While debugging i noticed that the module (and all other modules registered) gets hit every single time the client requests a resource (also when it requests images, stylesheets, javascript files (etc.)).
This happens both when running on a IIS 7 server in integrated pipeline mode, and debugging through the webdev server (in non- integrated pipeline mode)
As i am developing a website with a lot images which usually wont be cached by the client browser it will hit the modules a lot of unnessecary times.
I am using MVC and its routing mechanishm (System.Web.Routing.UrlRoutingModule).
When creating a new website the runAllManagedModulesForAllRequests attribute for the IIS 7 (system.webServer) section is per default set to true in the web.config, which as the name indicates make it call all modules for every single request.
If i set the runAllManagedModulesForAllRequests attribute to false, no modules will get called.
It seems that the reason for this is because of the routing module or mvc (dont know excactly why), which causes that the asp.net (aspx) handler never gets called and therefore the events and the modules never gets called (one time only like supposed).
I tested this by trying to call "mydomain.com/Default.aspx" instead of just "mydomain.com/" and correctly it calls the modules only once like it is supposed.
How do i fix this so it only calls the modules once when the page is requested and not also when all other resources are requested ?
Is there some way i can register that all requests should fire the asp.net (aspx) handler, except requests for specific filetype extensions ?
Of course that wont fix the problem if i choose to go with urls like /content/images/myimage123 for the images (without the extension). But i cant think of any other way to fix it.
Is there a better way to solve this problem ?
I have tried to set up an ignoreRoute like this routes.IgnoreRoute("content/{*pathInfo}"); where the content folder contains all the images, javascripts and stylesheets in seperat subfolders, but it doesnt seem to change anything.
I can see there a many different possibilites when setting up a handler but I cant seem to figure out how it should be possible to setup one that will make it possible to use the routing module and have urls like /blog/post123 and not call the modules when requesting images, javascripts and stylesheets (etc.).
Hope anyone out there can help me ?
Martin
The problem seems to be the routing module.
The solution is to move images, css, js to a subdomain, or you can probably register which filetypes/extensions the routing module should ignore.
The following code is what I use in every MVC Application in order to avoid the overhead caused by the routing system on serving static files, javascript, css, etc:
public static void RegisterRoutes(RouteCollection routes)
{
routes.RouteExistingFiles = false;
routes.LowercaseUrls = true;
routes.AppendTrailingSlash = true;
routes.IgnoreRoute("Content/{*pathInfo}");
routes.IgnoreRoute("Scripts/{*pathInfo}");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
/* ... */
}

Resources