diff --git a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php
index a96e0e14dcffd27a95deca1d510b83f8350aef19..d7a72b430fbb806fa4914b6948855053cd7d4fb0 100644
--- a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php
+++ b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php
@@ -132,7 +132,7 @@ public function processAttachments(AttachmentsInterface $response) {
    *   An array of commands ready to be returned as JSON.
    */
   protected function buildAttachmentsCommands(AjaxResponse $response, Request $request) {
-    $ajax_page_state = $request->request->all('ajax_page_state');
+    $ajax_page_state = $request->get('ajax_page_state');
 
     // Aggregate CSS/JS if necessary, but only during normal site operation.
     $optimize_css = !defined('MAINTENANCE_MODE') && $this->config->get('css.preprocess');
diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php
index 627b041e0489e672d54f68c7316644897d69789d..5e1cc95e7494deea13c40caaf9e62df453e06fb3 100644
--- a/core/lib/Drupal/Core/Render/Element/RenderElement.php
+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -244,6 +244,7 @@ public static function processAjaxForm(&$element, FormStateInterface $form_state
    *   - #ajax['event']
    *   - #ajax['prevent']
    *   - #ajax['url']
+   *   - #ajax['type']
    *   - #ajax['callback']
    *   - #ajax['options']
    *   - #ajax['wrapper']
@@ -340,6 +341,7 @@ public static function preRenderAjaxForm($element) {
       // to be substantially different for a JavaScript triggered submission.
       $settings += [
         'url' => NULL,
+        'type' => 'POST',
         'options' => ['query' => []],
         'dialogType' => 'ajax',
       ];
diff --git a/core/lib/Drupal/Core/Theme/AjaxBasePageNegotiator.php b/core/lib/Drupal/Core/Theme/AjaxBasePageNegotiator.php
index f4eec9b7a1a89386d3619eadcdc656cc65cb9553..ff50dc3eb065a642c13e57c80f307ab35c5eaedd 100644
--- a/core/lib/Drupal/Core/Theme/AjaxBasePageNegotiator.php
+++ b/core/lib/Drupal/Core/Theme/AjaxBasePageNegotiator.php
@@ -65,7 +65,7 @@ public function __construct(CsrfTokenGenerator $token_generator, ConfigFactoryIn
    * {@inheritdoc}
    */
   public function applies(RouteMatchInterface $route_match) {
-    $ajax_page_state = $this->requestStack->getCurrentRequest()->request->all('ajax_page_state');
+    $ajax_page_state = $this->requestStack->getCurrentRequest()->get('ajax_page_state');
     return !empty($ajax_page_state['theme']) && isset($ajax_page_state['theme_token']);
   }
 
@@ -73,7 +73,7 @@ public function applies(RouteMatchInterface $route_match) {
    * {@inheritdoc}
    */
   public function determineActiveTheme(RouteMatchInterface $route_match) {
-    $ajax_page_state = $this->requestStack->getCurrentRequest()->request->all('ajax_page_state');
+    $ajax_page_state = $this->requestStack->getCurrentRequest()->get('ajax_page_state');
     $theme = $ajax_page_state['theme'];
     $token = $ajax_page_state['theme_token'];
 
diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index ec18625bf656d9358218d585f1a04e3e2714fbf3..32d8cf08ac431384d64e75f47232c06cc98fdb3b 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -325,6 +325,13 @@
         elementSettings.url = href;
         elementSettings.event = 'click';
       }
+      const type = $linkElement.data('ajax-type');
+      /**
+       * In case of setting custom ajax type for link we rewrite ajax.type.
+       */
+      if (type) {
+        elementSettings.type = type;
+      }
       Drupal.ajax(elementSettings);
     });
   };
@@ -391,6 +398,7 @@
    */
   Drupal.Ajax = function (base, element, elementSettings) {
     const defaults = {
+      type: 'POST',
       event: element ? 'mousedown' : null,
       keypress: true,
       selector: base ? `#${base}` : null,
@@ -591,7 +599,7 @@
       },
       dataType: 'json',
       jsonp: false,
-      type: 'POST',
+      type: ajax.type,
     };
 
     if (elementSettings.dialog) {
diff --git a/core/modules/big_pipe/src/Render/BigPipe.php b/core/modules/big_pipe/src/Render/BigPipe.php
index 0461890b7143de1ba3d087bf94a2b6ef00f22353..75adfebe3a876a89871e79dd08af84243184d314 100644
--- a/core/modules/big_pipe/src/Render/BigPipe.php
+++ b/core/modules/big_pipe/src/Render/BigPipe.php
@@ -465,7 +465,7 @@ protected function sendNoJsPlaceholders($html, $no_js_placeholders, AttachedAsse
       // - the HTML to load the CSS can be rendered.
       // - the HTML to load the JS (at the top) can be rendered.
       $fake_request = $this->requestStack->getMainRequest()->duplicate();
-      $fake_request->request->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())]);
+      $fake_request->query->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())]);
       try {
         $html_response = $this->filterEmbeddedResponse($fake_request, $html_response);
       }
@@ -575,7 +575,7 @@ protected function sendPlaceholders(array $placeholders, array $placeholder_orde
       // - the attachments associated with the response are finalized, which
       //   allows us to track the total set of asset libraries sent in the
       //   initial HTML response plus all embedded AJAX responses sent so far.
-      $fake_request->request->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())] + $cumulative_assets->getSettings()['ajaxPageState']);
+      $fake_request->query->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())] + $cumulative_assets->getSettings()['ajaxPageState']);
       try {
         $ajax_response = $this->filterEmbeddedResponse($fake_request, $ajax_response);
       }
diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js
index bae75722339166f4ec37fa1cb2f246e9d304c5df..6e30c173680cb4dd1b06074dfe80bf5d58179998 100644
--- a/core/modules/views/js/ajax_view.js
+++ b/core/modules/views/js/ajax_view.js
@@ -90,6 +90,7 @@
     this.element_settings = {
       url: ajaxPath + queryString,
       submit: settings,
+      type: 'GET',
       setClick: true,
       event: 'click',
       selector,
@@ -127,6 +128,7 @@
     const selfSettings = $.extend({}, this.element_settings, {
       event: 'RefreshView',
       base: this.selector,
+      type: 'GET',
       element: this.$view.get(0),
     });
     this.refreshViewAjax = Drupal.ajax(selfSettings);
@@ -201,6 +203,7 @@
       submit: viewData,
       base: false,
       element: link,
+      type: 'GET',
     });
     this.pagerAjax = Drupal.ajax(selfSettings);
   };
diff --git a/core/modules/views/src/Controller/ViewAjaxController.php b/core/modules/views/src/Controller/ViewAjaxController.php
index 1b0188982e58b4074d2880636d128a035cfe3d14..67caeb62b9c28417de0182eb54882b0eea84584b 100644
--- a/core/modules/views/src/Controller/ViewAjaxController.php
+++ b/core/modules/views/src/Controller/ViewAjaxController.php
@@ -12,8 +12,6 @@
 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Path\CurrentPathStack;
-use Drupal\Core\Render\BubbleableMetadata;
-use Drupal\Core\Render\RenderContext;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Routing\RedirectDestinationInterface;
 use Drupal\Core\Ajax\ScrollTopCommand;
@@ -112,10 +110,10 @@ public static function create(ContainerInterface $container) {
    *   Thrown when the view was not found.
    */
   public function ajaxView(Request $request) {
-    $name = $request->request->get('view_name');
-    $display_id = $request->request->get('view_display_id');
+    $name = $request->get('view_name');
+    $display_id = $request->get('view_display_id');
     if (isset($name) && isset($display_id)) {
-      $args = $request->request->get('view_args', '');
+      $args = $request->get('view_args', '');
       $args = $args !== '' ? explode('/', Html::decodeEntities($args)) : [];
 
       // Arguments can be empty, make sure they are passed on as NULL so that
@@ -124,10 +122,10 @@ public function ajaxView(Request $request) {
         return ($arg == '' ? NULL : $arg);
       }, $args);
 
-      $path = $request->request->get('view_path');
-      $dom_id = $request->request->get('view_dom_id');
+      $path = $request->get('view_path');
+      $dom_id = $request->get('view_dom_id');
       $dom_id = isset($dom_id) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $dom_id) : NULL;
-      $pager_element = $request->request->get('pager_element');
+      $pager_element = $request->get('pager_element');
       $pager_element = isset($pager_element) ? intval($pager_element) : NULL;
 
       $response = new ViewAjaxResponse();
@@ -164,10 +162,9 @@ public function ajaxView(Request $request) {
           $this->currentPath->setPath('/' . ltrim($path, '/'), $request);
         }
 
-        // Add all POST data, because AJAX is always a post and many things,
+        // Add all POST data, because AJAX is sometimes a POST and many things,
         // such as tablesorts, exposed filters and paging assume GET.
         $request_all = $request->request->all();
-        unset($request_all['ajax_page_state']);
         $query_all = $request->query->all();
         $request->query->replace($request_all + $query_all);
 
@@ -190,16 +187,7 @@ public function ajaxView(Request $request) {
         // Reuse the same DOM id so it matches that in drupalSettings.
         $view->dom_id = $dom_id;
 
-        $context = new RenderContext();
-        $preview = $this->renderer->executeInRenderContext($context, function () use ($view, $display_id, $args) {
-          return $view->preview($display_id, $args);
-        });
-        if (!$context->isEmpty()) {
-          $bubbleable_metadata = $context->pop();
-          BubbleableMetadata::createFromRenderArray($preview)
-            ->merge($bubbleable_metadata)
-            ->applyTo($preview);
-        }
+        $preview = $view->preview($display_id, $args);
         $response->addCommand(new ReplaceCommand(".js-view-dom-id-$dom_id", $preview));
         $response->addCommand(new PrependCommand(".js-view-dom-id-$dom_id", ['#type' => 'status_messages']));
 
diff --git a/core/modules/views/src/Form/ViewsForm.php b/core/modules/views/src/Form/ViewsForm.php
index 766e366d134f39914ea525f06eb5d5e893960431..8b274fe2c0580e7fff2cb0b7e374aba0d1cb1fa8 100644
--- a/core/modules/views/src/Form/ViewsForm.php
+++ b/core/modules/views/src/Form/ViewsForm.php
@@ -157,7 +157,7 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu
     $form = [];
 
     $query = $this->requestStack->getCurrentRequest()->query->all();
-    $query = UrlHelper::filterQueryParameters($query, [], '');
+    $query = UrlHelper::filterQueryParameters($query, ['_wrapper_format'], '');
 
     $options = ['query' => $query];
     $form['#action'] = $view->hasUrl() ? $view->getUrl()->setOptions($options)->toString() : Url::fromRoute('<current>')->setOptions($options)->toString();
diff --git a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
index 00454912af121b32cc88906c7e3690046f3e7b10..d4a73743320da151f98a609b3f17c18ab9338a36 100644
--- a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
+++ b/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
@@ -98,8 +98,6 @@ public function testBasicPagination() {
     $this->assertCount(5, $rows);
     $this->assertStringContainsString('Node 6 content', $rows[0]->getHtml());
     $link = $page->findLink('Go to page 3');
-    // Test that no unwanted parameters are added to the URL.
-    $this->assertEquals('?status=All&type=All&langcode=All&items_per_page=5&order=changed&sort=asc&page=2', $link->getAttribute('href'));
     $this->assertNoDuplicateAssetsOnPage();
 
     $this->clickLink('Go to page 3');
diff --git a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php
index af6f8a135e904693dc6207e672654e234fbb7a92..d6b881851a32ed0e34ee787f028d5fb636194e35 100644
--- a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php
+++ b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php
@@ -182,18 +182,18 @@ public function testAccessDeniedView() {
    */
   public function testAjaxView() {
     $request = new Request();
-    $request->request->set('view_name', 'test_view');
-    $request->request->set('view_display_id', 'page_1');
-    $request->request->set('view_path', '/test-page');
-    $request->request->set('_wrapper_format', 'ajax');
-    $request->request->set('ajax_page_state', 'drupal.settings[]');
-    $request->request->set('type', 'article');
+    $request->query->set('view_name', 'test_view');
+    $request->query->set('view_display_id', 'page_1');
+    $request->query->set('view_path', '/test-page');
+    $request->query->set('_wrapper_format', 'ajax');
+    $request->query->set('ajax_page_state', 'drupal.settings[]');
+    $request->query->set('type', 'article');
 
     [$view, $executable] = $this->setupValidMocks();
 
     $this->redirectDestination->expects($this->atLeastOnce())
       ->method('set')
-      ->with('/test-page?type=article');
+      ->with('/test-page?ajax_page_state=drupal.settings%5B%5D&type=article');
     $this->currentPath->expects($this->once())
       ->method('setPath')
       ->with('/test-page', $request);
@@ -211,18 +211,18 @@ public function testAjaxView() {
    */
   public function testAjaxViewViewPathNoSlash() {
     $request = new Request();
-    $request->request->set('view_name', 'test_view');
-    $request->request->set('view_display_id', 'page_1');
-    $request->request->set('view_path', 'test-page');
-    $request->request->set('_wrapper_format', 'ajax');
-    $request->request->set('ajax_page_state', 'drupal.settings[]');
-    $request->request->set('type', 'article');
+    $request->query->set('view_name', 'test_view');
+    $request->query->set('view_display_id', 'page_1');
+    $request->query->set('view_path', 'test-page');
+    $request->query->set('_wrapper_format', 'ajax');
+    $request->query->set('ajax_page_state', 'drupal.settings[]');
+    $request->query->set('type', 'article');
 
     [$view, $executable] = $this->setupValidMocks();
 
     $this->redirectDestination->expects($this->atLeastOnce())
       ->method('set')
-      ->with('test-page?type=article');
+      ->with('test-page?ajax_page_state=drupal.settings%5B%5D&type=article');
     $this->currentPath->expects($this->once())
       ->method('setPath')
       ->with('/test-page');
diff --git a/core/tests/Drupal/Tests/Core/Theme/AjaxBasePageNegotiatorTest.php b/core/tests/Drupal/Tests/Core/Theme/AjaxBasePageNegotiatorTest.php
index 9c19f9ea68feb429a53c587b034d22cbd166fa07..be5985da8a70925d451dfb7292662028f794cfe4 100644
--- a/core/tests/Drupal/Tests/Core/Theme/AjaxBasePageNegotiatorTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/AjaxBasePageNegotiatorTest.php
@@ -55,8 +55,10 @@ protected function setUp(): void {
    * @dataProvider providerTestApplies
    */
   public function testApplies($request_data, $expected) {
-    $request = new Request([], $request_data);
-    $request->request = new InputBag($request->request->all());
+    $request = new Request();
+    foreach ($request_data as $key => $data) {
+      $request->query->set($key, $data);
+    }
     $route_match = RouteMatch::createFromRequest($request);
     $this->requestStack->push($request);
 
@@ -80,8 +82,8 @@ public function testDetermineActiveThemeValidToken() {
     $theme = 'claro';
     $theme_token = 'valid_theme_token';
 
-    $request = new Request([], ['ajax_page_state' => ['theme' => $theme, 'theme_token' => $theme_token]]);
-    $request->request = new InputBag($request->request->all());
+    $request = new Request();
+    $request->query->set('ajax_page_state', ['theme' => $theme, 'theme_token' => $theme_token]);
     $this->requestStack->push($request);
     $route_match = RouteMatch::createFromRequest($request);
 
@@ -97,8 +99,8 @@ public function testDetermineActiveThemeValidToken() {
   public function testDetermineActiveThemeInvalidToken() {
     $theme = 'claro';
     $theme_token = 'invalid_theme_token';
-
-    $request = new Request([], ['ajax_page_state' => ['theme' => $theme, 'theme_token' => $theme_token]]);
+    $request = new Request();
+    $request->query->set('ajax_page_state', ['theme' => $theme, 'theme_token' => $theme_token]);
     $request->request = new InputBag($request->request->all());
     $this->requestStack->push($request);
     $route_match = RouteMatch::createFromRequest($request);
@@ -118,7 +120,8 @@ public function testDetermineActiveThemeDefaultTheme() {
     // theme token. See system_js_settings_alter().
     $theme_token = '';
 
-    $request = new Request([], ['ajax_page_state' => ['theme' => $theme, 'theme_token' => $theme_token]]);
+    $request = new Request([]);
+    $request->query->set('ajax_page_state', ['theme' => $theme, 'theme_token' => $theme_token]);
     $request->request = new InputBag($request->request->all());
     $this->requestStack->push($request);
     $route_match = RouteMatch::createFromRequest($request);