Add HTTP Headers Using #attached in Drupal 7

Today, I discovered an undocumented but cool feature in Drupal 7. If you’ve been doing any work with the Drupal 7 Form API, you probably know about the #attached property that you can add to any element. The #attached property allows you to associate JavaScript files, special settings to go into Drupal.settings, CSS files, or require the loading of a library specified in a hook_library call. It’s a really handy way to avoid having to find an appropriate place and use a bunch of drupal_add_js() or drupal_add_css() calls in your code.

What I discovered today is that you can also attach HTTP Headers to be set in the page response when an element is rendered. First, let’s look at where it is being used in drupal core:

common.inc, Line 310: http://api.drupal.org/api/drupal/includes%21common.inc/function/_drupal_default_html_head/7


 

This function is adding a <meta> tag that identifies that this page was generated using Drupal 7. It then adds to the #attached property the following (reformatted for readability):


 

And that’s it! If you inspect the HTTP Headers sent to you when you load a page, you’ll see an X-Generator header that identifies this site as being built with Drupal 7.

Web Inspector of HTTP Response Headers

So how might you use this when you’re writing your own custom code?

Here’s a hypothetical scenario where I think this might come in handy:

Imagine that you have created your own CAPTCHA system and it gets added to forms that are available to anonymous visitors.1 For performance you want most of your pages to be cached by Drupal and by your visitor’s browsers, so you have caching enabled. However, you want to make sure that your visitor’s browsers don’t cache the page with an old CAPTCHA on it. An easy way to address this would be to add an HTTP Cache-Control header whenever your CAPTCHA gets rendered.

Here’s some imaginary code:


 

Now, whenever the form with your CAPTCHA element gets rendered, Drupal will send Cache-Control headers to instruct your browser (or a reverse proxy cache like Varnish) not to cache that page.


  1. DISCLAIMER: I make no claims to know all the intricacies of creating a CAPTCHA system, so this hypothetical might be wildly inaccurate to how one would really build this sort of system. The point is here to illustrate how you can attach HTTP Headers with form elements or other renderable items. 
  • Claus

    Thanks, very useful! :=)