I am having an issue with ajax caching, This was a problem in IE browser too but i fixed it by Writing the Following code.
response.setHeader("Cache-Control", "no-cache");
response.setHeader("expires","-1");
response.setHeader("pragma","no-cache");
But I see Safari4.0 on MAC is Caching the Ajax request(We have a requirment to support this). Fire Fox never a problem. Regarding this "Expire" i am setting it to -1, i see lot of places it is set 0 or some old date from past. Will it make a difference?
Send an extra parameter with your GET request that will never be the same, for example, the current timestamp. Something like:
url = url + '&nocache=' + new Date().getTime();
This will prevent caching.
First, a note on your Expires header. Your question doesn't specify what server framework you're using, so I'm not sure if this is applicable. However, it looks like you might be sending an invalid Expires header.
The RFC requires Expires to be a date, however you appear to be setting the header to a literal "-1". There are many frameworks that have an expires property on their HTTP response object that takes an int and automatically calculates a date that is that number of seconds from now.
Use a HTTP inspector to ensure that your server is sending a validly formatted date and not -1 in the Expires header.
You might try making your Cache-Control header more restrictive:
response.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate");
must-revalidate tells caches that they must obey any freshness information you give them. HTTP allows caches to serve stale representations under special conditions; by specifying this header, you’re telling the cache that you want it to strictly follow your rules. [1]
According to RFC 2616 section 9.5 about POST
Responses to this method are not cacheable, unless the response
includes appropriate Cache-Control or Expires header fields. However,
the 303 (See Other) response can be used to direct the user agent to
retrieve a cacheable resource.
So, the browser must not cache POST responses, unless the response specifies otherwise. In the same time, browsers may cache GET responses, unless the response specifies otherwise. So, for the requests that should not be cached, such as AJAX requests, POST is preferrable method.
If you, for any reason, don't want to use POSTs for AJAX, you should use the trick mentioned by minitech, it is in fact widely used to force browser to load current version of any resource.
Related
I need to log URLs that are linking to my site in a Java Servlet.
It's available in the HTTP referer header. You can get it in a servlet as follows:
String referrer = request.getHeader("referer"); // Yes, with the legendary misspelling.
You, however, need to realize that this is a client-controlled value and can thus be spoofed to something entirely different or even removed. Thus, whatever value it returns, you should not use it for any critical business processes in the backend, but only for presentation control (e.g. hiding/showing/changing certain pure layout parts) and/or statistics.
For the interested, background about the misspelling can be found in Wikipedia.
Actually it's:
request.getHeader("Referer"),
or even better, and to be 100% sure,
request.getHeader(HttpHeaders.REFERER),
where HttpHeaders is com.google.common.net.HttpHeaders
The URLs are passed in the request: request.getRequestURL().
If you mean other sites that are linking to you? You want to capture the HTTP Referrer, which you can do by calling:
request.getHeader("referer");
As all have mentioned it is
request.getHeader("referer");
I would like to add some more details about security aspect of referer header in contrast with accepted answer. In Open Web Application Security Project(OWASP) cheat sheets, under Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet it mentions about importance of referer header.
More importantly for this recommended Same Origin check, a number of HTTP request headers can't be set by JavaScript because they are on the 'forbidden' headers list. Only the browsers themselves can set values for these headers, making them more trustworthy because not even an XSS vulnerability can be used to modify them.
The Source Origin check recommended here relies on three of these
protected headers: Origin, Referer, and Host, making it a pretty
strong CSRF defense all on its own.
You can refer Forbidden header list here. User agent(ie:browser) has the full control over these headers not the user.
After reading the following thread:
Setting a custom Content-Range Header using Restlet
I tried setting a custom unitname in the Range for the entity. This does not solve the Problem.
final Range range = new Range();
range.setUnitName("items");
range.setIndex(0);
range.setSize(20);
[...]
getResponseEntity().setRange(range);
getResponseEntity().setSize(100);
The response now contains the following headers:
Content-Range:"items 0-19/100"
But Restlet also reads the range.size (20 in this case) and puts this as Content-Length automatically. Which results in:
Content-Length:"20"
This causes the client (e.g. Browser to stop reading after 20Bytes. (This also causes a null-pointer exception on the server, since the outputstream gets closed unexpectedly.)
The offical Restlet Documentation: http://restlet.com/technical-resources/restlet-framework/guide/2.3/core/http-headers-mapping
says Content-Length is available as message.entity.size, but this needs to be set to 100 to achieve the desired String in the Content-Range. This looks like a bug to me since range.size is used to calculate the content-length, not the entity size.
I can not set the Content-Length manually, since this is also a standard Header, and any manual changes to the standard headers are ingored.
The "Fix" proposed in the mentioned thread, only changes the Unitname - not the real unit - of the Range specified. It is still interpreted as bytes as is unusable as such.
Using the values in Range twice - for the content-range as well as the content-legth seems to be the problem.
Is there any new way to manually override the headers , or make them dojo compatible?
Manual changes are blocked in the HeaderUtils called by the ServerAdapter, causing the: "WARNING: Addition of the standard header [...] is not allowed..." warning.
support will be added in future 2.3.8 release of Restlet Framework.
I'm trying to cache data with OKHttp's native cache; my problem is that I don't have control over the server side data, and the response header Cache-Control is coming back with a "no-cache" value.
Is there anyway to intercept the request to add in a header to cache the data that's coming back using OkHttp? (I'd also like to cache specific requests if possible).
Thank you!
Best Regards,
Christopher Steven
OkHttp doesn't currently offer a mechanism to defeat Cache-Control: no-cache. OkHttp will end up validating the response with the server, but if the server says the stored response is still good then the response body won't need to be retransmitted.
We've got a feature request outstanding that wants something like this, though it's difficult because it may mean a single request yields multiple responses.
Just in case anyone else comes across this 18 months late... you can now "defeat" Cache-Control: no-cache through adding an interceptor as a network interceptor (so it updates the server response before OkHttp processes it).
There is a good example on the OkHttp wiki at https://github.com/square/okhttp/wiki/Interceptors#rewriting-responses.
Hope this helps.
I'm connecting to URLs with Java (HttpURLConnection).
I have noticed that in some cases, the response code is 3xx but the 'Location' header is empty.
How does a client browser know where to redirect after receiving this kind of HTTP response?
Thanks
Not all 3xx replies can redirect automatically.
300 provides multiple URLs in the response body, not in the Location header. The client/user has to decide which one to retrieve next.
301, 302, 303, and 307 provide a Location only if the next URL is known. Otherwise, the client/user has to decide what to do next.
304 is not a redirect. It is a response to a conditional GET, where the requested content has not changed since the requested criteria was last satisfied.
305 always provides a Location to the required proxy to connect to.
306 is not used anymore.
If you look at the HTTP spec on some of the 3xx status codes, some of them only SHOULD provide a Location header.
How does a client browser know where to redirect after receiving this
kind of HTTP response?
It doesn't. It's up to the client to handle what to do in that case.
Location headers redirect the user agent to retrieve another URI reference when used with 3xx redirection status codes, except for 304 Not Modified. Both absolute URIs and relative references can be provided, including empty references which refer to the current resource (see the URI specification for further information).
Still, only Firefox and old Edge accept empty Location headers; the new Edge and Chrome don't. Although HTTP redirects are only meant to redirect to different resources or URIs (see RFC 7231 section 6.4), all browsers implement non-empty Location headers that explicitly refer to the same page.
Whenever the user agent receives a redirection status code but no Location header (or an invalid Location header or in the case of Chrome, an empty Location header) it will not redirect but show the response body. This also applies when the user disables automatic redirection. Therefore the response body should also include the respective link.
Empty Location headers may obviously introduce redirect loops. Nevertheless, the status code 303 See Other could be used in conjunction with an empty Location header to implement the Post/Redirect/Get idiom using the very same URI. This idiom prevents users from resubmitting the same form using POST when reloading the page because 303 See Other requires the user agent to use the GET request method when following the new Location. 301 Moved Permanently and 302 Found may also change the request method to GET (but they also may not); 307 Temporary Redirect and 308 Permanent Redirect never change the request method.
While this use case seems kind of elegant I would not recommend to implement it because browser support diverges.
It turns out in Jetty, when you attach a cookie, it not only adds a cookie to the HTTP response header, it also alters the value of the Expires HTTP header!
((HttpServletResponse)response).addCookie(cookie);
I need Jetty to stop screwing around with the correct/proper expiry settings.
On a side note, Is there a particular/good reason for it to be behaving like this? My guess is that Jetty is assuming that if a cookie has been set, the content is always dynamic, and hence should be set to expired so that it is not cached.
Update: Testing this using Jetty 8.1.8.v20121106
Just took a walk through the Jetty 8 codebase.
Here are the situations in the codebase where Expires (as a HTTP Response header) is forced to a value, or removed if present.
Any HTTP 206 response (forced removal, per RFC2616 spec)
Use of org.eclipse.jetty.server.handler.MovedContextHandler (forced if unset)
During Form Authentication, if the need to respond with an error, via Dispatch handling (forced removal)
During a Form Authentication challenge response (forced removal)
That's it for Expires as a HTTP Response Header.
However, since you pointed this out as a part of .addCookie(), I'd like to point out that there is also a Cookie spec Expires header, as part of the Cookie value string, found in the Set-Cookie logic on a response.
This will force the Cookie Expires header if the Cookie.setMaxAge() value is 0 or greater. This is done to work around various browser bugs that do not honor Max-Age= until Expires= is also provided on the Cookie value.
Default behavior of Cookie:
Cookie.setMaxAge(-1); will disable both Max-Age= and Expires=
Cookie.setMaxAge(0); will result in Expires=00:00:00 UTC on 1 January 1970 (start of unix epoch)
Cookie.setMaxAge(60000); will result in a Expires= 1 minute in the future.
Version 1 Cookie behavior (aka Cookie.setVersion(1)):
Cookie.setMaxAge(-1); will disable both Max-Age= and Expires=
Cookie.setMaxAge(0); will result in Max-Age=0 and Expires=00:00:00 UTC on 1 January 1970 (start of unix epoch)
Cookie.setMaxAge(60000); will result in Max-Age=60000 and a Expires= 1 minute in the future.