I am rewriting a bunch of forms around a new paradigm, trying to simplify the mechanism used to prevent reprocessing of obsolete form data if the user plays with the back button. I redid it to the minimum test case that works in FF21, i.e. .10 (!), Opera12.15, but the only way with Chrome 27.0 and Safari 5.1.7 - not in browsers, which I would expect problems with, so that this is probably my own mistake.
Form view.php always sends post.php, which does all the work, and then redirects to view.php. (Some of them are design pages where some users repeat many times.) My goals were to avoid the message โThe browser should resend dataโ so that the browser does not use cached views and does not allow view.php to leave a long trace in the history. (Some sources claim that PRG prevents this.) All three goals are implemented in FF, Opera, and IE, where the story does not grow. Chrome and Safari show a trail of identical pageviews in history. Looking at the request / response headers, it looks like Chrome does a full GET of any historical page, but displays a mixture of historical and current field values โโon one page (!). It seems to me that the most difficult aspect for me is the presentation of a combination of values โโthat never coexisted on one page. Viewing the source in Chrome always shows an updated copy. And I'm talking about the behavior of accurate distilled examples below, and not about their more complex version.
Field 1 echoes the internal counter and ignores user input. It acts in the same strange way, whether it is read-only or not.
Field two user echoes. Usually I copy or add a field to it.
view.php
<?php session_start(); header('Cache-Control:private,no-store,no-cache,must-revalidate,post-check=0,pre-check=0'); header('Pragma: no-cache'); $cval = !isset($_SESSION['counter']) ? 0 : $_SESSION['counter']; $word = !isset($_SESSION['word']) ? '' : htmlentities($_SESSION['word'],ENT_QUOTES,'UTF-8',FALSE); echo <<<HTM <pre> <form method='POST' action='post.php'> <input type='text' name='count' value='$cval'/> <input type='text' name='word' value='$word'/> <input type='submit' name='doit' value='Submit'/> </form> </pre> HTM; ?>
post.php
<?php session_start(); if(!isset($_SESSION['counter'])): $_SESSION['counter'] = 1; else: $_SESSION['counter'] += 1; endif; $_SESSION['word'] = !isset($_POST['word']) ? '' : $_POST['word']; header('Location: view.php'); ?>
If I start backing up my history, Chrome typically displays the updated Field-one value, but it displays the historical Field-two values. Sometimes it shows historical on both. Without this inconsistency, I assume that it was an inability to prevent the server (in paired networks) or the proxy server from caching the page.
It does the same if I add the heading "Expires: -1".
I can handle the recognition of an obsolete form; what I cannot do is not allow the user to reach or send it. An increment of the GET argument in view.php will prevent unpredictable cached views, but it will create an explicit history in all browsers and suggest people turn the ratchet again.
Why is this happening and being fixed?