In an MVC5 project we encounter a problem with caching of the bundled resources (js/css).
According to the mvc docs, by default the bundles should be cached. And it works in other projects. However, here, no matter what configurations, the response headers for our resources are
Cache-Control: no-cache, no-store
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/javascript; charset=utf-8
Date: Wed, 01 Jul 2015 11:22:11 GMT
Expires: -1
Keep-Alive: timeout=5, max=100
Pragma: no-cache
Server: Microsoft-IIS/8.5
Transfer-Encoding: chunked
Vary: Accept-Encoding
I can't figure out where this is coming from as we are not disabling cache anywhere. Any ideas?
As I suggested in the comment Igor claimed that in Global.asax there were code for disabling caching:
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));
Response.Cache.SetNoStore();
Igor just to inform you these lines is one of the suggested way to fix 'browser back button' scenario (but as you can see with some cons). Simple scenario steps:
Login to application - looged in user is redirected to the home page
Logout - user redirected to the login page
Click back browser button - User should not be redirected to the home page but with enabled caching it could be an issue.
Please check the back browser button funcionality. If the scenario which I wrote is a problem for you please just use atribute
[OutputCache]
with proper parameters.
Regards Piotr
Related
I have set all headers that I know of to disable caching (even disabling ETAG) on my server, yet Safari still occasionally (about 50% times) caches my requests.
Workflow
I am implementing oauth 1, so:
Browser makes GET /api/user request
Server returns 405
Browser redirects to 3rd party website to authenticate
Browser is redirected to api/callback which stores some info into cookie.
Browser is redirected back to original route.
Browser makes GET /api/user request which should be successful, however it gets 405 served from disk cache instead.
Request summary from Safari Network Inspector
Summary
URL: http://localhost:3000/api/user
Status: 405 Method Not Allowed
Source: Disk Cache
Request
No request, served from the disk cache.
Response
Transfer-Encoding: Identity
Content-Type: application/json; charset=utf-8
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0
Vary: Cookie, Accept-Encoding
Date: Wed, 23 Jan 2019 11:34:23 GMT
Content-Encoding: gzip
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Connection: close
x-powered-by: Express
Conclusion
I have no idea what's wrong and I will greatly appreciate any help. My
Safari version is 12.0.2. I wasn't able to replicate this issue with Chrome.
Use Vary: *. This magically solved my problem.
This answer helped me: https://stackoverflow.com/a/2068353/1364158
Alternatively, you can really force browser to load a new version of request by including some meaningless random query arg in your url, e.g. /api/user?ts=18284
Background:
I'm working on a rails app that will open up articles inside the app itself via an iframe (with a navbar at the top from my app, kind of like StumbleUpon). But I've noticed some websites that publish articles (examples: pitchfork.com, vox.com, theverge.com) prevent themselves from being loaded in an iframe by setting X-Frame-Options to SAMEORIGIN or DENY.
My current plan to work around this is to look at the header for the link and examine it to see if it contains X-Frame-Options. If so, I will set it to forego the iframe and just open up the original site in a new tab.
This method seems to work for some websites (like pitchfork.com) because when I request the header from pitchfork.com, I get the following:
server: nginx/1.4.6 (Ubuntu)
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
date: Wed, 27 Jan 2016 17:47:54 GMT
x-varnish: 912263733 912263044
age: 8
via: 1.1 varnish
connection: keep-alive
Problem:
For some websites (like vox.com), when I load them in an iframe, the chrome developer console tells me that x-frame-options is preventing the site from loading in an iframe. But when I examine the header, x-frame-options is nowhere to be found! All I get is this:
server: nginx/1.6.2
date: Wed, 27 Jan 2016 17:26:15 GMT
content-type: text/html
content-length: 172
connection: close
How is vox.com doing this? For further clarification, I tried using this tool that I found in another stackoverflow post and it also failed to correctly detect that vox.com was blocking iframes via x-frame-options.
1) Is Vox able to set the x-frame-options somewhere other than the header? If the latter, how can I detect and find that?
2) Any other alternate strategies you recommend for detecting iframe-unfriendly sites so that I can have them set to open in a new tab instead?
Take a look at the network traffic recorded in the Chrome console. In your app, you're looking at the headers of the HTTP 301 Moved Permanently response, which then redirects you to the location that does return the X-Frame-Options: SAMEORIGIN header.
Other methods, such as the newer Content-Security-Policy header or JavaScript code, may be used by other websites to prevent iframe embedding. But in the case of vox.com, you're simply looking at the headers of the wrong response.
I have a default page that can display 3 different contents depending on whether:
The user is not logged in
The user is logged in but hasn't set something up yet
The user is logged in and has set something up
What's happening is that (1) and (2) will sometimes be displayed when it should be the other one. After I ctrl-r, the correct version displays.
This is nothing to do with the browser back button, it happens after clicking a menu option to go to the default page or performing some action that takes the user to the default page.
I also have a route set up for the page such that it's possible to append it with a username. eg: http://www.example.com/user1234
I mention this in case it may have something to do with it.
This is what I've tried to stop the caching:
<%# OutputCache Location="None" VaryByParam="None" %>
That didn't work so I tried (in Page_Load):
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache)
Response.Cache.SetNoStore()
Any ideas what I'm doing wrong?
ETA
As per a couple of comments, I tried it in Chrome incognito mode and there is no problem. I tried with the console open as well to see the headers but unfortunately the problem goes away then. Here's the headers anyway:
Request
GET / HTTP/1.1 Host: localhost:2873 Connection: keep-alive
Cache-Control: max-age=0 Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/34.0.1847.92 Safari/537.36 Referer: .../signin
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
Cookie: ...
Response
HTTP/1.1 200 OK Cache-Control: no-cache, no-store Pragma: no-cache
Content-Type: text/html; charset=utf-8 Content-Encoding: gzip
Expires: -1 Vary: Accept-Encoding Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?...
X-Powered-By: ASP.NET Date: Thu, 27 Mar 2014 20:17:39 GMT
Content-Length: 3045
ETA2
I've been testing in Chrome and I've just found out there's no problem in FireFox.
If I login/out/in/out... there is no problem
If I login/out then log in with the wrong password a couple of times (causing postbacks in the login page), and then log in again correctly, it always displays the incorrect logout page in Chrome.
I was having the same problem. What I did was place this
Response.CacheControl = "No-cache";
within the page load before any of the other code runs. The issue that this solved for me was similar tor yours. When a user logs in, a drop down box is loaded with different stores that the user belongs too. If I changed their stores, they could navigate back to the page and see their old set of stores. I placed the above in the page load and this solved my issues within IE, Chrome and Firefox. Hopefully something as easy as this will fix your problem.
To resolve the caching issue with particular file you have to add
<location path="WebForm1.aspx">
<system.webServer>
<caching enabled="false" enableKernelCache="false" />
</system.webServer>
</location>
into your web.config's configuration section.
You can also do it using IIS. Steps to setup no cache using IIS is as below.
Go to your sites Content View. Right click on file and switch to features view.
With file selected open Output Caching open from IIS.
From Action Pane on right side click on Edit Feature Setting, and from dialog box untick Enable cache and Enable kernal cache. Click Ok to save setting into web.config.
take a look here and checking if it could be hopefull http://dotnet.dzone.com/articles/programmatically-clearing-0
I followed this tutorial, http://symfony.com/doc/current/cookbook/controller/error_pages.html, and have error.html.twig and error.json.twig within app/Resources/TwigBundle/views/Exception/
Even though the content type of the request is set to application/json, all errors default to the html version of the error page.
The format of the route is also defined:
http://symfonyinstall/api/v1/users.json
Request Header:
Accept: application/json
Content-Type: application/json
Connection: keep-alive
Origin: chrome-extension: //rest-console-id
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.162 Safari/535.19
Response Header:
Status Code: 404
date: Sun, 29 Apr 2012 06:54:35 GMT
Content-Encoding: gzip
X-Powered-By: PHP/5.3.10
Transfer-Encoding: chunked
Connection: keep-alive
Server: nginx
Content-Type: text/html; charset=UTF-8
cache-control: no-cache
I'm out of ideas... and I really need a json version of the errors for my API to work...
I just hit the same problem, and although your question is quite old and symfony bumped a few versions up since then, the problem is still relevant, so even if you don't need to know it any more, maybe somebody else will.
Your original problem was probaly caused by error described here, but there wasn't much going on about it after initial post. Since then the entire codebase was updated, so while the same symptoms reappeared, the error is not related. I am posting it here because anybody looking for an answer these days will probably find this question (as I did :).
Even when returing JsonResponse directly form kernel exception handler, it will still have Content-Type: text/html; charset=UTF-8. This stumped me so much that I used netcat to make a manual request without any smart software in between, and it turns out that the response in such case has actually two different Content-Type headers:
HTTP/1.0 500 Internal Server Error
Connection: close
X-Powered-By: PHP/5.5.9-1ubuntu4.17
Content-Type: text/html; charset=UTF-8
Cache-Control: private, must-revalidate
Content-Type: application/json
pragma: no-cache
expires: -1
X-Debug-Token: 775c55
X-Debug-Token-Link: http://127.0.0.1:8000/_profiler/775c55
Date: Thu, 27 Oct 2016 23:08:31 GMT
Now, double Content-Type header is not something you see everyday. It seems that this is implemented in Symfony\Component\Debug\ExceptionHandler class that is only used in debug mode. In order to be as robust as possible, it first renders standard Symfony error page that describes thrown exception. Rendered content is not sent back directly, instead it leverages PHP's output buffering feature to buffer and store produced output. Then it attempts to produce custom error page from framework. In case this fails, previously prepared message is sent.
Output buffering however works only for message content, and not for headers - these are always sent directly. This problem only appears in debug environment, and unusual content types on error are only common in WebAPI, where debug mode is arguably of little use. This makes exposure surface relatively small, but if an application that offers both WebAPI and end-user interface needs to be tested, this might become a problem.
Solving this problem without modifying internal Symfony files doesn't seem possible. Output control sits deep within symfony kernel and doesn't offer any configuration. Anyway, I am not convinced of benefits of such solution. If anyone could explain to me what could have happened during custom exception handler that would make default handler useless in case it failed?
Maybe user code messing with ob_* functions?
I'm implementing a simple REST service with the WCF Web API and attempt to set HTTP headers in order to cache responses.
For a simple GET like this
http://localhost:49302/my/2
the response headers look like this:
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 24 Jan 2012 18:18:44 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 233
Cache-Control: max-age=120
Vary: Accept
Expires: Tue, 24 Jan 2012 18:20:44 GMT
Last-Modified: Tue, 24 Jan 2012 18:18:15 GMT
Content-Type: application/xml; charset=utf-8
The intent is that the client should cache the resource for two minutes.
However, using the WCF Web API Test Client, the behavior is inconsistent across various browsers:
In Firefox (9.0.1) the request is cached, and first after two minutes is a new version of the resource displayed. This behavior is as expected.
In Chrome (16.0.912.77 m) the cache headers aren't respected at all. A new version of the resource is being fetched for every GET request. This behavior is not expected (by me, at least).
In Internet Explorer (9) the behavior is the same as in Chrome.
Why doesn't Chrome and IE respect the cache headers?
Is it a bug in the WCF Web API Test Client?
Caching is hard to get right. The fact that a browser may ignore cache directives certainly doesn't help.
According to this document IE never cached any request with a Vary header containing anything but Accept-Encoding and User-Agent
If I test this with a 15 seconds cache period and I just set the MaxAge and MustRevalidate it seems to work fine with IE9, FireFox and Chrome.
Web API HttpResponseMessage:
result = new HttpResponseMessage<Book>(book);
result.Headers.CacheControl = new CacheControlHeaderValue();
result.Headers.CacheControl.MaxAge = TimeSpan.FromSeconds(15);
result.Headers.CacheControl.MustRevalidate = true;
return result;
Response headers:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 25 Jan 2012 09:13:32 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 98
Cache-Control: must-revalidate, max-age=15
Content-Type: application/json; charset=utf-8
Connection: Close
I am not sure the MustRevalidate is really required but it is recommended to use it. See the specs here.
Test to replace localhost with "real domain" so the WCF Test Client or Chrome/IE doesnt have any special tricks for localhost.