-
Notifications
You must be signed in to change notification settings - Fork 24
Why do I get an error if I hit my browser's reload button after a redirect using persist="true"?
The redirect command with a persist attribute set to true is used to persist complex objects across the redirect. The reason this is necessary is because a redirect is done on the client side, which means that a new request is made from the client to the server. This is the point of a redirect because redirects are used when it's desired to have the URL change in the browser so that any actions that were taken prior to the redirect will not be repeated if the user reloads the page in their browser.
A classic example where a redirect should be used is in an ecommerce application. Imagine that when the user clicks a "Finalize Order" button, this announces a processOrder
event, and after the order is successfully processed an orderConfirmation
event is announced. If the orderConfirmation
event is announced using the announce
command in the XML config file or via the announceEvent()
function, then everything occurs on the server and the URL in the user's browser doesn't change. Because the URL hasn't changed, if the user were to reload the page in their browser, unless other precautions have been taken their order would be processed again since a reload would announce the processOrder
event again.
Redirects avoid this problem by performing a client-side redirect (similar to what occurs when <cflocation>
is used), which does change the URL in the browser. Server-side redirects have the advantage of all being part of the same request; therefore multiple event announcements can share data. When a client-side redirect is performed this is an entirely new request, so although simple name/value pairs may be included in the URL's query string, the ability to persist complex variables (query objects, CFCs, etc.) across the redirect is lost.
When a redirect command is executed with the persist attribute set to true, however, complex variables can be persisted across the redirect. This is done by using what in the Java Spring world (and elsewhere) is called a "flash scope," which simply means complex variables are temporarily placed in the server's RAM using a persist key that is unique to each redirect, and the persist key is included in the URL of the redirect command. After the client-side redirect is performed, the persist key is used to retrieve the data that was persisted for the redirect, thereby making it available via the event object. In terms of the availability of the data it is just as if the redirect were performed on the server side, but the URL has changed which avoids the potential issue with a page reload that was outlined above.
The flash scope, as the name indicates, is not designe d for long-term storage. It is available for the duration of the redirect, but once the data is retrieved after the redirect it is no longer available. What this means is that if the user clicks the reload button in their browser after the redirect, Mach-II will attempt to locate data using the persist ID in the URL, and when the data is not found in the flash scope an error will be thrown.
While this behavior is to be expected, it is not unusual for the user to reload a page in their browser which means an error will be thrown. Unfortunately since every situation is different there isn't much that can be done within Mach-II itself to obviate this situation, but developers can use one of several approaches in their application code if this situation is causing issues.