7

i have a requirement where a value should not be cached in the server nor the browser as an cookie over domains and sessions.

So i choosed to permanent-redirect to the value

Servlet:

@Override
protected void service(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    String key = request.getParameter("key");
    String val = request.getContentType();
    if (val != null && val.length() == 0) {
        val = null;
    }
    String repeatText = request.getParameter("repeatText");
    if (val != null && repeatText == null) {
        response.setStatus(301); // moved permanent
        response.addHeader("Location", "?repeatText=" + val);
        System.out.println("Write");
    } else {
        if (repeatText != null) {
            response.setContentLength(repeatText.length());
            response.addHeader("pragma", "no-cache");
            response.addIntHeader("expires", BROWSER_CACHE_DAYS);
            response.getWriter().write(repeatText);
            System.out.println("Read and cache!");
        } else {
            response.sendError(304); // use from cache!
            System.out.println("Send use from cache.");
        }
    }
}

Script:

<input class="username" />
<button>Login</button>

<script>
jQuery.ajax('theservlet?key=username').done(function(v){jQuery('.username').val(v);});
jQuery('button').click(function(){
  jQuery.ajax('theservlet?key=username',{contentType:jQuery('.username').val()})
});
</script>

Console-output:

Send use from cache.
--- i enter username and press the button ---
Write
Read and cache!
--- now i make a reload ---
Send use from cache.

After the reaload from the browsercache does not return the username i inserted.

Why does the browser not cache?

EDIT: Added for explaintaition

CupawnTae
  • 14,192
  • 3
  • 29
  • 60
Grim
  • 1,938
  • 10
  • 56
  • 123
  • what does the address bar say before and after the reload? – CupawnTae Apr 29 '15 at 12:25
  • `http://localhost:8080/` – Grim Apr 29 '15 at 12:43
  • BHSM is the BrowserHistoryStorageMechanism. – Grim Apr 30 '15 at 08:48
  • 1
    By the way, if you want the browser to cache the result, why are you calling `response.addHeader("pragma", "no-cache");`? – CupawnTae Apr 30 '15 at 08:59
  • @CupawnTae i like the prevent any proxy from caching. Not the Browser. Does the pragma prevents the browser from caching too? – Grim Apr 30 '15 at 09:11
  • Actually, it's supposed to only be used as a request header according to the spec, so what it does as a response header is undefined at best. Either way, it's not restricted to proxies, so I'd be tempted to take it out, but not sure if that's making a difference here. Diagram is useful btw. – CupawnTae Apr 30 '15 at 09:16
  • I found the pragma in the last call to the servlet in the diagram. The pragma is transformed into a request-header and prevents proxys from caching if you ever like to change the value `abc`. – Grim Apr 30 '15 at 09:46
  • It also (officially at least) tells the server that the *client doesn't want a cached copy*. Since you're manually controlling the server cache mechanism, that shouldn't be an issue on the server-side, but if the client is sending that header, maybe that means it has cleared it from the cache. Anyway, I presume you've tried removing it and it hasn't solved the initial issue, but I would be tempted to leave it out of the equation until you get things working, just to rule it out as a culprit. – CupawnTae Apr 30 '15 at 09:50
  • You might get more help if you changed the question title. I've never come across the initialism BHSM before, and googling it doesn't find anything either, so you could be losing people straight away because they don't recognize it. Also, the actual issue is not that clear at a glance. Something like "Browser doesn't cache 301 redirect responses to AJAX requests" might attract someone who knows the answer straight away. – CupawnTae May 02 '15 at 07:37
  • Did you mean to use `key` instead of `val` in the call to addHeader? If the browser did not send an `if-modified-since` header it's probably not expecting a 304. Generally an `if-modified-since` is only sent if the last request to that url returned a `Last-modified` header. – Devon_C_Miller May 05 '15 at 18:50

3 Answers3

0

Your request is an ajax call which is an async request to your servlet in this case your redirection in serverside does not affect to clientside. This request works like seperate thread in your browser.

So you should specify response data (url in this case with query string). After servlet response in your ajax success callback you should specify location to redirect event.

For redirection after ajax success window.location.href = reponseUrl; , instead of redirect you can set the value of your input.

Otherwise just submit form and redirect via your servlet.

İlker Korkut
  • 3,129
  • 3
  • 30
  • 51
0

Redirecting the ajax request won't redirect the browser to the new location, and if it did you wouldn't have your page any more, you'd just have the response from the servlet.

So then when you refresh the page, you're requesting the original URL from scratch again and the username is lost.

You could add the username into the URL directly in javascript:

jQuery('button').click(function(){
  var username=jQuery('.username').val();
  jQuery.ajax('theservlet?key=username',{contentType:username});
  window.location.hash=username;
});

This will append "#username" to the URL in the address bar. And then on page load you can populate the input from the request parameter if present:

jQuery('.username').val( window.location.hash );
CupawnTae
  • 14,192
  • 3
  • 29
  • 60
0

Even if you do get the 301 mechanism working, you won't have any guarantees on how long the browser will cache the redirect. I don't have an answer immediately for why the 301s are not being cached for you, however if you're ok with the browser storing the username somewhere (after all, that's what you're trying to do with the 301s), and it's just that you specifically don't want it to be stored in a cookie, then sessionStorage or localStorage would be the right choice:

sessionStorage.setItem("username", username);

and

var username = sessionStorage.getItem("username");

or use localStorage to store it persistently across sessions.

Docs here

CupawnTae
  • 14,192
  • 3
  • 29
  • 60
  • These Storages are restricted to one Domain or Session. This is different from BHSM-Mechanism. I like to let everybody share this information across different pages domains, extensions and plugins. – Grim Apr 30 '15 at 09:42
  • Ok. Probably worth adding that requirement to the question. – CupawnTae Apr 30 '15 at 09:47