diff --git a/core/core.services.yml b/core/core.services.yml
index 328acd8..91ce48b 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -873,6 +873,10 @@ services:
     tags:
       - { name: route_processor_outbound }
     arguments: ['@csrf_token']
+  path_processor_accept:
+    class: Drupal\Core\PathProcessor\PathProcessorAccept
+    tags:
+      - { name: path_processor_inbound, priority: 0 }
   transliteration:
     class: Drupal\Core\Transliteration\PHPTransliteration
   flood:
diff --git a/core/lib/Drupal/Core/ContentNegotiation.php b/core/lib/Drupal/Core/ContentNegotiation.php
index 857f9d5..1dacb7d 100644
--- a/core/lib/Drupal/Core/ContentNegotiation.php
+++ b/core/lib/Drupal/Core/ContentNegotiation.php
@@ -30,6 +30,10 @@ class ContentNegotiation {
    *   The normalized type of a given request.
    */
   public function getContentType(Request $request) {
+    if ($request->getRequestFormat(NULL)) {
+      return $request->getRequestFormat(NULL);
+    }
+
     // AJAX iframe uploads need special handling, because they contain a JSON
     // response wrapped in <textarea>.
     if ($request->get('ajax_iframe_upload', FALSE)) {
diff --git a/core/lib/Drupal/Core/EventSubscriber/ContentControllerSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ContentControllerSubscriber.php
index 32f9565..86b0eda 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ContentControllerSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ContentControllerSubscriber.php
@@ -48,7 +48,7 @@ public function __construct(ContentNegotiation $negotiation) {
   public function onRequestDeriveFormat(GetResponseEvent $event) {
     $request = $event->getRequest();
 
-    if (!$request->attributes->get('_format')) {
+    if (!$request->getRequestFormat(NULL)) {
       $request->setRequestFormat($this->negotiation->getContentType($request));
     }
   }
diff --git a/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php
index fcc51a3..1ee5808 100644
--- a/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php
@@ -76,7 +76,7 @@ public function onViewRenderArray(GetResponseForControllerResultEvent $event) {
     $request = $event->getRequest();
     $result = $event->getControllerResult();
 
-    $format = $request->getRequestFormat();
+    $format = $request->getRequestFormat(NULL);
 
     // Render the controller result into a response if it's a render array.
     if (is_array($result)) {
diff --git a/core/lib/Drupal/Core/PathProcessor/PathProcessorAccept.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorAccept.php
new file mode 100644
index 0000000..c5b1cec
--- /dev/null
+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorAccept.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\PathProcessor\PathProcessorAccept.
+ */
+
+namespace Drupal\Core\PathProcessor;
+
+use Symfony\Component\HttpFoundation\Request;
+
+class PathProcessorAccept implements InboundPathProcessorInterface {
+
+  protected $mapping = [
+    'json' => 'json',
+    'html' => 'html',
+    'drupal_ajax' => 'drupal_ajax',
+    'drupal_dialog' => 'drupal_dialog',
+    'drupal_modal' => 'drupal_modal',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processInbound($path, Request $request) {
+    // Sets the request format based upon the incoming .extension.
+    $match = [];
+    if (preg_match('/\.([a-z_]+)$/', $path, $match)) {
+      if (isset($this->mapping[$match[1]])) {
+        $request->setRequestFormat($this->mapping[$match[1]]);
+      }
+      // -1 for the dot.
+      $path = substr($path, 0, strlen($path) - strlen($match[1]) - 1);
+    }
+    return $path;
+  }
+
+  public function addMapping($extension, $format) {
+    $this->mapping[$extension] = $format;
+  }
+
+}
diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index 82d6044..9745681 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -52,7 +52,7 @@
           element_settings.url = $(this).attr('href');
           element_settings.event = 'click';
         }
-        element_settings.accepts = $(this).data('accepts');
+        element_settings.format = $(this).data('format');
         element_settings.dialog = $(this).data('dialog-options');
         var base = $(this).attr('id');
         Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
@@ -216,6 +216,12 @@
     // 4. /nojs# - Followed by a fragment (e.g.: path/nojs#myfragment).
     this.url = this.url.replace(/\/nojs(\/|$|\?|#)/g, '/ajax$1');
 
+    // Append the extension for the URL.
+    var extension = element_settings.format || 'drupal_ajax';
+    if (extension) {
+      this.url += '.' + extension;
+    }
+
     // Set the options for the ajaxSubmit function.
     // The 'this' variable will not persist inside of the options object.
     var ajax = this;
@@ -248,9 +254,6 @@
         }
       },
       dataType: 'json',
-      accepts: {
-        json: element_settings.accepts || 'application/vnd.drupal-ajax'
-      },
       type: 'POST'
     };
 
diff --git a/core/modules/block/src/BlockListBuilder.php b/core/modules/block/src/BlockListBuilder.php
index 9afbef2..65236ba 100644
--- a/core/modules/block/src/BlockListBuilder.php
+++ b/core/modules/block/src/BlockListBuilder.php
@@ -361,7 +361,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         ]),
         'attributes' => array(
           'class' => array('use-ajax', 'block-filter-text-source'),
-          'data-accepts' => 'application/vnd.drupal-modal',
+          'data-format' => 'drupal_modal',
           'data-dialog-options' => Json::encode(array(
             'width' => 700,
           )),
diff --git a/core/modules/ckeditor/js/ckeditor.js b/core/modules/ckeditor/js/ckeditor.js
index 67e2399..bdfe4fa 100644
--- a/core/modules/ckeditor/js/ckeditor.js
+++ b/core/modules/ckeditor/js/ckeditor.js
@@ -161,7 +161,7 @@
       var $content = $('<div class="ckeditor-dialog-loading"><span style="top: -40px;" class="ckeditor-dialog-loading-link"><a>' + Drupal.t('Loading...') + '</a></span></div>');
       $content.appendTo($target);
       new Drupal.ajax('ckeditor-dialog', $content.find('a').get(0), {
-        accepts: 'application/vnd.drupal-modal',
+        format: 'drupal_modal',
         dialog: dialogSettings,
         selector: '.ckeditor-dialog-loading-link',
         url: url,
diff --git a/core/modules/config/src/Form/ConfigSync.php b/core/modules/config/src/Form/ConfigSync.php
index 58451e7..c11619b 100755
--- a/core/modules/config/src/Form/ConfigSync.php
+++ b/core/modules/config/src/Form/ConfigSync.php
@@ -280,7 +280,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
             'url' => Url::fromRoute($route_name, $route_options),
             'attributes' => array(
               'class' => array('use-ajax'),
-              'data-accepts' => 'application/vnd.drupal-modal',
+              'data-format' => 'drupal_modal',
               'data-dialog-options' => json_encode(array(
                 'width' => 700
               )),
diff --git a/core/modules/hal/src/HalServiceProvider.php b/core/modules/hal/src/HalServiceProvider.php
new file mode 100644
index 0000000..8e2115d
--- /dev/null
+++ b/core/modules/hal/src/HalServiceProvider.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\hal\HalServiceProvider.
+ */
+
+namespace Drupal\hal;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\DependencyInjection\ServiceModifierInterface;
+
+class HalServiceProvider implements ServiceModifierInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alter(ContainerBuilder $container) {
+    if ($definition = $container->getDefinition('path_processor_accept')) {
+      $definition->addMethodCall('addMapping', ['hal_json', 'hal_json']);
+    }
+  }
+
+}
diff --git a/core/modules/node/config/install/views.view.frontpage.yml b/core/modules/node/config/install/views.view.frontpage.yml
index b5d02e9..bd24cb0 100644
--- a/core/modules/node/config/install/views.view.frontpage.yml
+++ b/core/modules/node/config/install/views.view.frontpage.yml
@@ -246,7 +246,7 @@ display:
     position: 2
     display_options:
       sitename_title: true
-      path: rss.xml
+      path: rss
       displays:
         page_1: page_1
         default: ''
diff --git a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
index ab25fde..027f017 100644
--- a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
+++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
@@ -61,7 +61,7 @@ public function dialog() {
       '#url' => Url::fromRoute('ajax_test.dialog_contents'),
       '#attributes' => array(
         'class' => array('use-ajax'),
-        'data-accepts' => 'application/vnd.drupal-modal',
+        'data-format' => 'drupal_modal',
       ),
     );
 
@@ -74,7 +74,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_contents'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-modal',
+            'data-format' => 'drupal_modal',
             'data-dialog-options' => json_encode(array(
               'width' => 400,
             ))
@@ -85,7 +85,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_contents'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-dialog',
+            'data-format' => 'drupal-dialog',
             'data-dialog-options' => json_encode(array(
               'target' => 'ajax-test-dialog-wrapper-1',
               'width' => 800,
@@ -104,7 +104,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_form'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-modal',
+            'data-format' => 'drupal_modal',
           ),
         ),
         'link6' => array(
@@ -112,7 +112,7 @@ public function dialog() {
           'url' => Url::fromRoute('contact.form_add'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-modal',
+            'data-format' => 'drupal_modal',
             'data-dialog-options' => json_encode(array(
               'width' => 800,
               'height' => 500,
@@ -124,7 +124,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_contents'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-dialog',
+            'data-format' => 'drupal-dialog',
             'data-dialog-options' => json_encode(array(
               'width' => 800,
             ))
diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php
index 67171ab..9f1f429 100644
--- a/core/modules/views/src/Plugin/views/display/Feed.php
+++ b/core/modules/views/src/Plugin/views/display/Feed.php
@@ -234,7 +234,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
         );
         break;
       case 'path':
-        $form['path']['#description'] = $this->t('This view will be displayed by visiting this path on your site. It is recommended that the path be something like "path/%/%/feed" or "path/%/%/rss.xml", putting one % in the path for each contextual filter you have defined in the view.');
+        $form['path']['#description'] = $this->t('This view will be displayed by visiting this path on your site. It is recommended that the path be something like "path/%/%/feed" or "path/%/%/rss", putting one % in the path for each contextual filter you have defined in the view.');
     }
   }
 
