3

A custom module I'm building has a page callback that creates and Inbox listing. When a user clicks an item in the inbox, another page callback displays the message, and it updates the database to record that it's been read.

The problem is that when the user presses Back, they get back to their local cache of the inbox which suggests it has not been read. If they reload, it's OK.

Is there a way (in hook_menu?) to flag that a page should not be cached/expires immediately?

7

If I understand your expectation correctly, it's less of a Drupal and more of a browser thing. When the user presses the Back button, if you don't want the browser to show a copy of the web page that it might already have, the Cache-Control header in your initial response must have no-store. Drupal by default, doesn't have this. You can confirm this by checking the definition of this function.

Simply overwriting the Cache-Control header seems to fix this on Opera 16, Firefox 23 and Chrome 30. However, on Safari 6, it doesn't. Turns out that it might be a known issue. So, we might have to turn to a Javascript hack for that.

In summary, including the snippet below in your page callback should do the trick for you. I have assumed Drupal 7.

// Add no-store in Cache-Control.
drupal_add_http_header(
  'Cache-Control', 
  'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', 
  FALSE
);
// Hack for Safari
drupal_add_js('jQuery(window).unload(function(){});', array('type' => 'inline'));

This seems to work on a fresh Drupal 7.22 install for an authenticated user. If the page in question has been asked to be stored in the Drupal cache or if you are using a contributed module that also messes with the response headers, this might not work as is for you.

Useful References

| improve this answer | |
  • WOW! Thank you for providing such an amazing answer! And it works (always a bonus). Apols that it's officially not a drupal thing, hope it will be still useful to others as a question. – artfulrobot Oct 7 '13 at 15:45
  • I have a similar issue but more in general for any page. Where should I put the above code to make pages not cached by the browser? – Antonello Jul 6 '16 at 7:44
2

To avoid particular page being cached, you may try either of the following:

  1. Add the following in page callback function of hook_menu:

    drupal_page_is_cacheable(FALSE);

    drupal_page_is_cacheable(): Determines the cache ability of the current page. Set it to FALSE if you want to disable caching for that page.

  2. Use the cacheexclude module: This module provides a simple way to exclude certain pages from being cached. Sometimes you want all pages to be cached for anonymous users except for one or two pages that have dynamic or random or rotating content. If those pages are cached, the dynamic parts cease to be dynamic. This module allows an administrator to selectively exclude certain paths from being cached so that dynamic content is actually dynamic.

If you want to disable the cache for particular page than you try the cacheexclude module that provides the UI for adding pages that doesn't need to be cached.

| improve this answer | |
  • I get Notice: Use of undefined constant CACHE_DISABLED - assumed 'CACHE_DISABLED' – artfulrobot Oct 7 '13 at 12:01
  • Well, no error, but it doesn't fix the problem. I fear some horrible JS polling fix... – artfulrobot Oct 7 '13 at 12:28
  • @artfulrobot Final update, Can you give this a try, I have check the above on my system and it seems to be working fine. Don't forget to clear the cache :) – Ankit Agrawal Oct 7 '13 at 12:52
  • Thanks Ankit for your perseverance! Still not quite working: I don't think Drupal is caching this page (I can always hit reload and get new results), but what I want is for Drupal to tell the browser that the page has expired so that when the user hits Back they don't get a stale page. Sorry, perhaps this is not possible? (which would explain the 2 anon 'close' requests! - wish people would be clear why they vote to close/vote down stuff...) – artfulrobot Oct 7 '13 at 13:27
  • Both these methods can be used to skip the Drupal cache exclusively for one or more pages. The way I see it, the question has nothing to do with the Drupal cache. Hence, this might not be useful probably in this scenario. – Amarnath Ravikumar Oct 7 '13 at 13:45
0

Try changing the following global variable on the page load:

$GLOBALS['conf']['cache'] = FALSE;

but the problem is that you cannot use this in hook_boot(), because it's already too late to disable the caching. But there is a patch for it, see: Allow hook_boot() to disable page cache. Unless you'll add it into your settings file.

See also: Dynamic Cache and CacheExclude modules.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.