Drupal 7 - HTTP/AJAX/JSON responses at same URL with Accept Header (like D8) Drupal 8 has this new amazing in-built functionality for handling requests from browsers and via AJAX at the same URL using the Accept header, which makes the CTools way of adding "nojs" to URLs, and then changing that to "js" in the JavaScript seems like a clever but antiquated hack.

Is there a cleaner way to do this, that could be considered a "best practice" for Drupal 7 going forward, that is more inline with how things are now done in Drupal 8?   Also, how does a traditional ajax response versus a json response factor into this?

Code examples would be highly useful here.
I am not sure whether this is clean or "best practice" but I am currently using something like this:

  // If the request has the header 'Accept: application/json'
  // return the output in JSON format and stop.
  if ($_SERVER['HTTP_ACCEPT'] == 'application/json') {
    drupal_add_http_header('Content-Type', 'application/json; utf-8');
    print json_encode($strings);
    exit;
  }


To see it in the context, here is the whole function:

&lt;?php
/**
 * Menu callback: translations/search.
 *
 * Search strings and translations using various filters.
 *
 * If the request header 'Accept: application/json' is set, then
 * the output will be in JSON, otherwise it will be an HTML page.
 * For example:
 *   curl -k -i -H 'Accept: application/json' \
 *        'https://dev.l10n.org.xx/translations/search?lng=sq&amp;words=space'
 */
function btrClient_search() {
  // Get the search parameters from the GET request.
  $params = btrClient_get_search_params();

  // Get the strings that match the search params.
  $btr = btr_user_is_authenticated() ?
    wsclient_service_load('btr') :
    wsclient_service_load('public_btr');
  $result = $btr-&gt;search($params);
  $filter = $result['filter'];
  $pager = $result['pager'];
  $strings = $result['strings'];

  // If the request has the header 'Accept: application/json'
  // return the output in JSON format and stop.
  if ($_SERVER['HTTP_ACCEPT'] == 'application/json') {
    drupal_add_http_header('Content-Type', 'application/json; utf-8');
    print json_encode($strings);
    exit;
  }

  // Add the CSS and JS files.
  drupal_add_css(drupal_get_path('module', 'btrClient') . '/editor/editor.css');
  drupal_add_js(drupal_get_path('module', 'btrClient') . '/editor/jquery.worddiff.js');
  drupal_add_js(drupal_get_path('module', 'btrClient') . '/editor/editor.js');

  // Add RTL style if the current language's direction is RTL.
  $languages = btrClient_get_languages();
  $lng = btrClient_get_translation_lng();
  if ($languages[$lng]['direction'] == LANGUAGE_RTL) {
    drupal_add_css(drupal_get_path('module', 'btrClient') . '/editor-rtl.css');
  }

  // Set the title.
  drupal_set_title(t('Search Translations'));

  // Add the filter form.
  $output = array(
    drupal_get_form('btrClient_filter_form', $filter),
  );

  // Output the strings.
  if (empty($strings)) {
    drupal_set_message(t('No strings found. Try adjusting the filter options.'));
  }
  else {
    pager_default_initialize($pager['number_of_items'], $pager['items_per_page']);
    $output[] = drupal_get_form('btrClient_translate_form', $strings, $lng);
  }

  return $output;
}


(Or check it out here: http://cgit.drupalcode.org/btrclient/tree/includes/search.inc