diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index da3a277..02bfe7b 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -951,6 +951,23 @@ function variable_del($name) {
 }
 
 /**
+ * Gets the page cache cid for this request.
+ *
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ *   The request for this page.
+ *
+ * @return string
+ *   The cid for this request.
+ */
+function drupal_page_cache_get_cid(Request $request) {
+  $cid_bits = array(
+    $request->getUri(),
+    Drupal::service('content_negotiation')->getContentType($request),
+  );
+  return md5(implode(':', $cid_bits));
+}
+
+/**
  * Retrieves the current page from the cache.
  *
  * Note: we do not serve cached pages to authenticated users, or to anonymous
@@ -958,23 +975,12 @@ function variable_del($name) {
  * from a form submission, the contents of a shopping cart, or other user-
  * specific content that should not be cached and displayed to other users.
  *
- * @param $check_only
- *   (optional) Set to TRUE to only return whether a previous call found a
- *   cache entry.
- *
  * @return
  *   The cache object, if the page was found in the cache, NULL otherwise.
  */
-function drupal_page_get_cache($check_only = FALSE) {
-  global $base_root;
-  static $cache_hit = FALSE;
-
-  if ($check_only) {
-    return $cache_hit;
-  }
-
+function drupal_page_get_cache(Request $request) {
   if (drupal_page_is_cacheable()) {
-    $cache = cache('page')->get($base_root . request_uri());
+    $cache = cache('page')->get(drupal_page_cache_get_cid($request));
     if ($cache !== FALSE) {
       $cache_hit = TRUE;
     }
@@ -2035,7 +2041,6 @@ function _drupal_bootstrap_page_cache() {
     $cache_enabled = $config->get('cache.page.use_internal');
   }
 
-  // @todo this is *criminal*. but, necessary, until we fix bootstrap ordering.
   $request = Request::createFromGlobals();
   // If there is no session cookie and cache is enabled (or forced), try
   // to serve a cached page.
@@ -2043,7 +2048,7 @@ function _drupal_bootstrap_page_cache() {
     // Make sure there is a user object because its timestamp will be checked.
     $user = drupal_anonymous_user();
     // Get the page from the cache.
-    $cache = drupal_page_get_cache();
+    $cache = drupal_page_get_cache($request);
     // If there is a cached page, display it.
     if (is_object($cache)) {
       $response = new Response();
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 1980f2f..8b4659a 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3166,11 +3166,9 @@ function _drupal_bootstrap_full($skip = FALSE) {
  * @see drupal_page_header()
  */
 function drupal_page_set_cache(Response $response, Request $request) {
-  global $base_root;
-
   if (drupal_page_is_cacheable()) {
     $cache = (object) array(
-      'cid' => $base_root . $request->getRequestUri(),
+      'cid' => drupal_page_cache_get_cid($request),
       'data' => array(
         'path' => $request->attributes->get('_system_path'),
         'body' => $response->getContent(),
diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php
index ca2d7b3..9b00237 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php
@@ -41,6 +41,29 @@ function setUp() {
   }
 
   /**
+   * Tests support for different cache items with different Accept headers.
+   */
+  function testAcceptHeaderRequests() {
+    $config = config('system.performance');
+    $config->set('cache.page.use_internal', 1);
+    $config->set('cache.page.max_age', 300);
+    $config->save();
+
+    $accept_header_cache_uri = 'system-test/page-cache/accept-header';
+    $json_accept_header = array('Accept: application/json');
+
+    $this->drupalGet($accept_header_cache_uri);
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'HTML page was not yet cached.');
+    $this->drupalGet($accept_header_cache_uri);
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'HTML page was cached.');
+
+    $this->drupalGet($accept_header_cache_uri, array(), $json_accept_header);
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Json response was not yet cached.');
+    $this->drupalGet($accept_header_cache_uri, array(), $json_accept_header);
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Json response was cached.');
+  }
+
+  /**
    * Tests support of requests with If-Modified-Since and If-None-Match headers.
    */
   function testConditionalRequests() {
diff --git a/core/modules/system/tests/modules/system_test/system_test.module b/core/modules/system/tests/modules/system_test/system_test.module
index ea10a04..2c3fbdd 100644
--- a/core/modules/system/tests/modules/system_test/system_test.module
+++ b/core/modules/system/tests/modules/system_test/system_test.module
@@ -6,6 +6,11 @@
  * Implements hook_menu().
  */
 function system_test_menu() {
+  $items['system-test/page-cache/accept-header'] = array(
+    'page callback' => 'system_test_accept_header',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
   $items['system-test/auth'] = array(
     'page callback' => 'system_test_basic_auth_page',
     'access callback' => TRUE,
@@ -280,3 +285,16 @@ function system_test_authorize_init_page($page_title) {
   system_authorized_init('system_test_authorize_run', drupal_get_path('module', 'system_test') . '/system_test.module', array(), $page_title);
   return new RedirectResponse($authorize_url);
 }
+
+/**
+ * Page callback: serves different responses based on the HTTP Accept header.
+ */
+function system_test_accept_header() {
+  if (\Drupal::request()->headers->get('Accept') == 'application/json') {
+    return drupal_json_encode(array('content' => 'oh hai this is json'));
+  }
+  else {
+    return "<html><body>oh hai this is html.</body></html>";
+  }
+}
+
diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module
index dbbca14..f058445 100644
--- a/core/modules/toolbar/toolbar.module
+++ b/core/modules/toolbar/toolbar.module
@@ -125,10 +125,10 @@ function _toolbar_initialize_page_cache() {
 
   // If we have a cache, serve it.
   // @see _drupal_bootstrap_page_cache()
-  $cache = drupal_page_get_cache();
+  $request = \Drupal::request();
+  $cache = drupal_page_get_cache($request);
   if (is_object($cache)) {
     $response = new Response();
-    $request = \Drupal::request();
     $response->headers->set('X-Drupal-Cache', 'HIT');
     date_default_timezone_set(drupal_get_user_timezone());
 
