diff --git a/core/includes/common.inc b/core/includes/common.inc
index fa4c0c9..a1d0c96 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -5003,24 +5003,6 @@ function drupal_json_decode($var) {
 }
 
 /**
- * Returns data in JSON format.
- *
- * This function should be used for JavaScript callback functions returning
- * data in JSON format. It sets the header for JavaScript output.
- *
- * @param $var
- *   (optional) If set, the variable will be converted to JSON and output.
- */
-function drupal_json_output($var = NULL) {
-  // We are returning JSON, so tell the browser.
-  drupal_add_http_header('Content-Type', 'application/json');
-
-  if (isset($var)) {
-    echo drupal_json_encode($var);
-  }
-}
-
-/**
  * Gets a salt useful for hardening against SQL injection.
  *
  * @return
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 6541e8d..0ecfcdd 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -7,6 +7,7 @@
 
 use Drupal\entity\EntityFieldQuery;
 use Drupal\Core\File\File;
+use Symfony\Component\HttpFoundation\JsonResponse;
 
 // Load all Field module hooks for File.
 require_once DRUPAL_ROOT . '/core/modules/file/file.field.inc';
@@ -318,7 +319,7 @@ function file_ajax_progress($key) {
     }
   }
 
-  drupal_json_output($progress);
+  return new JsonResponse($progress);
 }
 
 /**
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 466cd88..9015f67 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -12,6 +12,7 @@
  */
 
 use Drupal\node\Node;
+use Symfony\Component\HttpFoundation\JsonResponse;
 
 /**
  * Maximum length of menu name as entered by the user. Database length is 32
@@ -396,7 +397,7 @@ function menu_parent_options_js() {
   }
   $options = _menu_get_options(menu_get_menus(), $available_menus, array('mlid' => 0));
 
-  drupal_json_output($options);
+  return new JsonResponse($options);
 }
 
 /**
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index f34c766..c17e13a 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -5,6 +5,7 @@
  * Admin page callbacks for the system module.
  */
 
+use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 
@@ -2219,7 +2220,7 @@ function system_add_date_format_type_form_submit($form, &$form_state) {
  */
 function system_date_time_lookup() {
   $result = format_date(REQUEST_TIME, 'custom', $_GET['format']);
-  drupal_json_output($result);
+  return new JsonResponse($result);
 }
 
 /**
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 39755dc..2c0876d 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -5,6 +5,7 @@
  * Configuration system that lets administrators modify the workings of the site.
  */
 
+use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Response;
 
 /**
@@ -3438,7 +3439,7 @@ function system_timezone($abbreviation = '', $offset = -1, $is_daylight_saving_t
   // interpreted as the empty string.
   $abbreviation = $abbreviation ? $abbreviation : '';
   $timezone = timezone_name_from_abbr($abbreviation, intval($offset), $is_daylight_saving_time);
-  drupal_json_output($timezone);
+  return new JsonResponse($timezone);
 }
 
 /**
diff --git a/core/modules/system/tests/modules/database_test/database_test.module b/core/modules/system/tests/modules/database_test/database_test.module
index 4500f74..42a47e0 100644
--- a/core/modules/system/tests/modules/database_test/database_test.module
+++ b/core/modules/system/tests/modules/database_test/database_test.module
@@ -1,6 +1,7 @@
 <?php
 
 use Drupal\Core\Database\Query\AlterableInterface;
+use Symfony\Component\HttpFoundation\JsonResponse;
 
 /**
  * Implements hook_query_alter().
@@ -84,11 +85,10 @@ function database_test_menu() {
  */
 function database_test_db_query_temporary() {
   $table_name = db_query_temporary('SELECT status FROM {system}', array());
-  drupal_json_output(array(
+  return new JsonResponse(array(
     'table_name' => $table_name,
     'row_count' => db_select($table_name)->countQuery()->execute()->fetchField(),
   ));
-  exit;
 }
 
 /**
@@ -111,10 +111,9 @@ function database_test_even_pager_query($limit) {
 
   $names = $query->execute()->fetchCol();
 
-  drupal_json_output(array(
+  return new JsonResponse(array(
     'names' => $names,
   ));
-  exit;
 }
 
 /**
@@ -137,10 +136,9 @@ function database_test_odd_pager_query($limit) {
 
   $names = $query->execute()->fetchCol();
 
-  drupal_json_output(array(
+  return new JsonResponse(array(
     'names' => $names,
   ));
-  exit;
 }
 
 /**
@@ -168,10 +166,9 @@ function database_test_tablesort() {
   // We need all the results at once to check the sort.
   $tasks = $query->execute()->fetchAll();
 
-  drupal_json_output(array(
+  return new JsonResponse(array(
     'tasks' => $tasks,
   ));
-  exit;
 }
 
 /**
@@ -200,10 +197,9 @@ function database_test_tablesort_first() {
   // We need all the results at once to check the sort.
   $tasks = $query->execute()->fetchAll();
 
-  drupal_json_output(array(
+  return new JsonResponse(array(
     'tasks' => $tasks,
   ));
-  exit;
 }
 
 /**
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index f681c75..cd0691b 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -280,7 +280,7 @@ function form_test_menu() {
  * Form submit handler to return form values as JSON.
  */
 function _form_test_submit_values_json($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   drupal_exit();
 }
 
@@ -996,7 +996,7 @@ function form_test_form_state_values_clean_form($form, &$form_state) {
  */
 function form_test_form_state_values_clean_form_submit($form, &$form_state) {
   form_state_values_clean($form_state);
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit;
 }
 
@@ -1098,7 +1098,7 @@ function _form_test_checkbox($form, &$form_state) {
  * Return the form values via JSON.
  */
 function _form_test_checkbox_submit($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit();
 }
 
@@ -1207,7 +1207,7 @@ function form_test_select($form, &$form_state) {
  * Form submit handler for form_test_select().
  */
 function form_test_select_submit($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit();
 }
 
@@ -1379,7 +1379,7 @@ function form_test_range($form, &$form_state) {
  * Form submission handler for form_test_range().
  */
 function form_test_range_submit($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit;
 }
 
@@ -1506,7 +1506,7 @@ function form_test_email($form, &$form_state) {
  * Form submission handler for form_test_email().
  */
 function form_test_email_submit($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit();
 }
 
@@ -1539,7 +1539,7 @@ function form_test_url($form, &$form_state) {
  * Form submission handler for form_test_url().
  */
 function form_test_url_submit($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit();
 }
 
@@ -1739,7 +1739,7 @@ function _form_test_disabled_elements($form, &$form_state) {
  * Return the form values via JSON.
  */
 function _form_test_disabled_elements_submit($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit();
 }
 
@@ -1768,7 +1768,7 @@ function _form_test_input_forgery($form, &$form_state) {
  * Return the form values via JSON.
  */
 function _form_test_input_forgery_submit($form, &$form_state) {
-  drupal_json_output($form_state['values']);
+  print drupal_json_encode($form_state['values']);
   exit();
 }
 
diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc
index c84a6bd..48d0774 100644
--- a/core/modules/taxonomy/taxonomy.pages.inc
+++ b/core/modules/taxonomy/taxonomy.pages.inc
@@ -7,6 +7,7 @@
 
 use Drupal\taxonomy\Term;
 use Drupal\taxonomy\Vocabulary;
+use Symfony\Component\HttpFoundation\JsonResponse;
 
 /**
  * Menu callback; displays all nodes associated with a term.
@@ -166,5 +167,5 @@ function taxonomy_autocomplete($field_name, $tags_typed = '') {
     }
   }
 
-  drupal_json_output($term_matches);
+  return new JsonResponse($term_matches);
 }
diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc
index fcda92e..2c09daa 100644
--- a/core/modules/user/user.pages.inc
+++ b/core/modules/user/user.pages.inc
@@ -5,6 +5,7 @@
  * User page callback file for the user module.
  */
 
+use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 
 /**
@@ -19,7 +20,7 @@ function user_autocomplete($string = '') {
     }
   }
 
-  drupal_json_output($matches);
+  return new JsonResponse($matches);
 }
 
 /**
