7.x bootstrap.inc drupal_add_http_header($name, $value, $append = FALSE)

Sets an HTTP response header for the current page.

Note: When sending a Content-Type header, always include a 'charset' type, too. This is necessary to avoid security bugs (e.g. UTF-7 XSS).


$name: The HTTP header name, or the special 'Status' header name.

$value: The HTTP header value; if equal to FALSE, the specified header is unset. If $name is 'Status', this is expected to be a status code followed by a reason phrase, e.g. "404 Not Found".

$append: Whether to append the value to an existing header or to replace it.

24 calls to drupal_add_http_header()
aggregator_test_feed in modules/aggregator/tests/aggregator_test.module
Page callback. Generates a test feed and simulates last-modified and etags.
ajax_deliver in includes/ajax.inc
Packages and sends the result of a page callback as an Ajax response.
ajax_set_verification_header in includes/ajax.inc
Sets a response header for ajax.js to trust the response body.
authorize_access_denied_page in ./authorize.php
Renders a 403 access denied page for authorize.php.
drupal_deliver_html_page in includes/common.inc
Packages and sends the result of a page callback to the browser as HTML.

... See full list


includes/bootstrap.inc, line 1398
Functions that need to be loaded on every Drupal request.


function drupal_add_http_header($name, $value, $append = FALSE) {

  // The headers as name/value pairs.
  $headers =& drupal_static('drupal_http_headers', array());
  $name_lower = strtolower($name);
  if ($value === FALSE) {
    $headers[$name_lower] = FALSE;
  elseif (isset($headers[$name_lower]) && $append) {

    // Multiple headers with identical names may be combined using comma (RFC
    // 2616, section 4.2).
    $headers[$name_lower] .= ',' . $value;
  else {
    $headers[$name_lower] = $value;
    $name => $headers[$name_lower],
  ), TRUE);


corbacho’s picture

geerlingguy’s picture

Note that the way you set up an http header is different in Drupal 7 than in Drupal 6.

For example, in Drupal 6, it would be set by:

  drupal_set_header('Content-Type: text/csv; utf-8');

The equivalent, in Drupal 7:

   drupal_add_http_header('Content-Type', 'text/csv; utf-8');

Note the different parameters you pass into drupal_add_http_header(). Also, to add to the header (instead of replacing it with each call to drupal_add_http_header()), make sure you add a third parameter, set to TRUE.

nehajn’s picture

Example to set headers in drupal 7 so that your json output data also accessible from cross domain wrt. all request types.

function send_data()
 {  // How to call 
  set_mycustom_api_headers();  // calling headers
  $data_array = array()
  $data_array['content']          =   'test';
  echo $data_array = drupal_json_encode($data_array);

function set_mycustom_api_headers()
  drupal_add_http_header('Content-Type', 'application/json');
  drupal_add_http_header('Access-Control-Allow-Origin', "*");
  drupal_add_http_header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
selwynpolit’s picture

I've seen this function used this way to add a vary header (for example)

drupal_add_http_header('Vary', 'Cookie, fastly-ssl');

If there is already a call to set the vary header, this call will overwrite the existing Vary header which could be problematic for caching causing stale content to be delivered.
We should include the append parameter eg.

drupal_add_http_header('Vary', 'Cookie,fastly-ssl', TRUE);
ibejrex’s picture

Has anyone found a replacement for drupal_add_http_header() in D8?

osopolar’s picture

Yes, see issue #1839338: [meta] Remove drupal_set_*() drupal_add_*() in favour of #attached/response for out-of-band stuff.

For example to set status code in template_preprocess_node() or in template_preprocess_page(), you can write:

$variables['#attached']['http_header'] = array(
array('status', 401),