What key do browsers use to cache CSS files? - asp.net

I use an ASP.NET web handler to combine my CSS files.
The URL format that this requires is:
/Combiner.ashx?f=~/stylesheets/reset.css--~/stylesheets/base.css&t=text/css&v=3.1.4.2113
It takes any number of CSS files to combine followed by the type and finally the version number of the site assembly.
The HTTP expires header is set to one month in the future.
Since I'm including the version number in the query string I would have hoped that this would stop browsers serving up invalid content. However, the version number appears to be getting ignored and both Chrome and IE both think the content is not modified.
I have confirmed that the version number has definitely changed.
Any ideas as to why this is being ignored?

Related

Same CSS background specified multiple times

If you specify same image in different CSS selectors, will it be downloaded separately or later url's will use the first one?
.a {
background: url('image1.png');
}
...
.b {
background: url('image1.png');
}
Actually in all the browsers, we have browser cache. Once it is loaded it will not be loaded again. If the file size and names are same, there is no way it is going to be loaded again. You can track that using firebug or developertools.
Try it — when looking into caching issues, a tool like Firebug for
Firefox or the Developer Tools within Chrome are very beneficial. If
you open the 'Net' panel in either and reload a page, you will see
what HTTP status code was sent for each item. 304 (Not modified) means
that the item was retrieved locally from the cache.
As dthorpe says above, cache headers are important here. As well as
making sure that 'no-cache' hasn't been set, if you have access to
your server configuration you should be pro-active — if you know a
resource isn't going to change you should make sure to set either an
'Expires' header (which tells browsers a date after which the cached
copy should be considered stale) or a 'Cache-Control: max-age' header
(which gives a number of days/hours rather than a set date).
You can set different time-scales for different mime-types/folders
too, which allows you to get clients data to refresh HTML content
often, but images and stylesheets rarely.
Here's a nice intro video/article by Google that's worth checking out.
Highlighted are the proper answers from this stackoverfow question. It will be interesting for you if you try to know about how web browsers work.

Strange characters output on asp.net mvc page

Sometimes (randomly) my asp.net mvc application outputs page where single character is being replaced with weird question marks, as shown on image
This behavior is constant until data changes, and it does not disappear with page refresh. The whole page is in Georgian unicode. I am using asp.net mvc 3 with visual studio 2010 and iis express. This is also observed on published site to IIS 7.5. I have seen similar issues in asp.net webforms application too.
I have observed this behavior not only on db-provided data, but simple anchors, generated with html helper
TagBuilder addAnchor = new TagBuilder("a");
addAnchor.AddCssClass("add-item");
addAnchor.MergeAttribute("href", "#");
addAnchor.SetInnerText(SharedResources.Add); //resource item contains string დამატება
which output anchor "დამატ���ბა"
And this is not issue with page rendering on browser-side, as raw response already contains these symbols.
Update:
As it seems, disabling buffer output by setting Response.BufferOutput = false; removes weird characters from page. But I use Cassette for referencing bundles, and it cannot work with disabled buffer output - no scipts or stylesheets get referenced on page.
Has anyone of you had a similar problem? This is actually critical for me, as currently it affects data where that single character being damaged is the correct answer information of a multi-select test question.
I had the same bug. It is Cassette with a feature that rewrites the result HTML content (and needs BufferOutput set to true) to move referenced script and stylesheet tags to the top if needed.
See the IsHtmlRewritingEnabled option at http://getcassette.net/documentation/configuration.
When I turned off this feature, the bug has disappeared.
My observations:
It is appeared only with remote requests. Local requests are always ok.
The location of question marks is always constant for all clients, browsers and computers.
The location of question marks changes only after recompilation of the application.
I would imagine it's to do with character sets. I've had this issue when i've tried to display a character that isn't in a particular character set.
such as ’ or – (’ or –) in UTF-8 when the character hasn't been HTML encoded previously.
I too had output like this. In my case the source of error was within Views/web.config. An assembly was listed in pages/namespaces, which was not part of the referenced assemblies

Why adding version number to CSS file path?

I noticed some websites put the version numbers (especially) in the CSS file path. For example:
<link rel="stylesheet" type="text/css" href="style.css?v=12345678" />
What is the main purpose to put the version number? If the purpose is to remember when the CSS file was updated last time, shouldn't the version number added as a comment inside the CSS file?
From HTML5 ★ Boilerplate Docs:
What is ?v=1" '?v=1' is the JavaScript/CSS Version Control with
Cachebusting
Why do you need to cache JavaScript CSS? Web page designs are getting
richer and richer, which means more scripts and stylesheets in the
page. A first-time visitor to your page may have to make several HTTP
requests, but by using the Expires header you make those components
cacheable. This avoids unnecessary HTTP requests on subsequent page
views. Expires headers are most often used with images, but they
should be used on all components including scripts, stylesheets etc.
How does HTML5 Boilerplate handle JavaScript CSS cache? HTML5
Boilerplate comes with server configuration files: .htacess,
web.config and nginx.conf. These files tell the server to add
JavaScript CSS cache control.
When do you need to use version control with cachebusting?
Traditionally, if you use a far future Expires header you have to
change the component's filename whenever the component changes.
How to use cachebusting? If you update your JavaScript or CSS, just
update the "?v=1" to "?v=2", "?v=3" ... This will trick the browser
think you are trying to load a new file, therefore, solve the cache
problem.
It's there to make sure that you have the current version. If you change your website and leave the name as before, browser may not notice the change and use old CSS from its cache. If you add version, the browser will download the new stylesheet.
If you set caches to expire far in the future adding ?v=2 will let the server know this is a new file but you won't need to give it a unique name (saving you a global search and replace)
HTM5 boilerplate also includes it in their project.
Check this video also: HTML5 Boilerplate Walkthrough.
One of the reason could be to bypass file caching. Same name CSS files can be cached by the servers and may result in bad display if new version has has layout changes.
This is to optimise browser-caching. You can set the header for CSS files to never expire so the browser will always get it from its cache.
But if you do this, you'll get problems when changing the CSS file because some browsers might not notice the change. By adding/changing the version-parameter it's "another" request and so it won't be taken from the cache (but after the new version is cached, it's taken from there in the future to save bandwidth/number of requests until the version changes again).
A detailed explanation can be found at html5boilerplate.com.
My knowledge is pretty much out of date regarding websites, but the variable stored in the 'href' argument is received by the browser through HTTP. Using the usual tricks in URL-rewriting you could actually have an arbitrary script that produces CSS-output when called. That output can differ, depending on the argument.

'Open files based on content, not file extension' in IE 9

I am supporting a site for a client on the intranet. The site contains links to xml files. These xml files have a unique extension and are intended to be opened by a specific application. Using IE 8, we could support this by setting the option ‘Open files based on content, not file extension’ in Internet Options -> Security -> Custom Level. In IE 9, this option has been removed. Now these files open a new tab and display the xml.
Ideally, I’d like the file to just download through the download manager, but opening file in the application on the client machine would be acceptable as well. What is the best way to do this in IE 9? Is there a setting that I should adjust? Server side, I have tried adjusting the MIME type, but it seems that if I sent it to something unknown (e.g. application/octet-stream) IE determines the content. The last option I could think of would be to adjust the links such that they call an asp.net page that loads the contents of the xml into the response object but changes the header to contain Content-Disposition:"attachment;filename=file.ext”.
Any advice on the best way to solve this problem?
Content-Disposition:attachment is what you are looking for, yes. That is how you instruct browsers to download the file separately, and not try to display it.
You could use routing or rewriting to keep your file URLs, but have an ASHX handle the file so it can set that header. (don't use an ASPX; it's more than you need to just set some headers)
I think the work around that I was looking for was the fact that the 'Open files based on content, not file extension' option in IE8 was renamed, 'Enable MIME Sniffing' in IE9. But Andrew Barber's answer is the correct solution.

what is style.css?ver=1 tag?

I found out that some websites use css tag like style.css?ver=1. What is this?
What is purpose of ?ver=1?
How do I do it in code?
To avoid caching of CSS.
If the website updates their CSS they update the ver to a higher number, therefore browser is forced to get a new file and not use cached previous version.
Otherwise a browser may get a new HTML code and old CSS and some elements of the website may look broken.
Adding '?ver=1' makes the HTTP request look like a GET query with parameters, and well-behaved browsers (and proxies) will refuse to cache parameterized queries. Of course well-behaved browsers (and proxies) should also pay attention to the 'Cache-control: no-cache', 'Expires', 'Last-Modified', and 'ETag' response headers (all of which were added to HTTP to specify correct caching behavior).
The '?ver=1' method is an expensive way to force behavior when the site developer doesn't know how (or is too lazy) to implement the correct response headers. In particular, it means that every page request is going to force requesting that CSS file, even though, in practice, CSS files change rarely, if at all.
My recommendation? Don't do it.
The purpose of the ?ver=1 is to parameterize the css file, so when they publish a new style.css file they up the version and it forces the client to download the new file, instead of pulling from the cached version.
If you are developing a web application in HTML and CSS or any other technology, and you are using some external CSS or JS files, you might notice one thing that in some cases if you made any changes to your existing .css or .js files then the browsers are not reflecting the changes immediately.
What happens in that case is that the browser do not download a fresh copy of the latest version of the .css and .js files, instead it uses those files stored in your local cache. As a result the changes you made recently are not visible to you.
<link rel="stylesheet" href="style.css?v=1.1">
The above case when you load the web page the browser will treat "style.css" as a different file along with "?v=1.1". Hence the browser is forced to download a fresh copy if the stylesheet or the script file.
I think that ?ver=1 is for the version no. of the web app. Every time a new build is created, the app can update the ver to the new version. This is so that the browser will load the new CSS file and not use the cached one (both use different file names).
You can refer to this site: http://www.knowlegezone.com/36/article/Technology/Software/JavaScript/CSS-Caching-Hack----javascript-as-well
IMO a better way to do this would be to include a hash generated off of the file size or a checksum based on the file contents or last-modified date. That way you don't have to update some version number and just let the number be driven off of the file's changing properties.

Resources