diff --git a/core/lib/Drupal/Core/Pager/PagerParameters.php b/core/lib/Drupal/Core/Pager/PagerParameters.php
index 9a70c74d1a5bd34748c4ceef4442fcd55100f129..b5b2cf9b71f29ec3921c25737854a923ae4367a2 100644
--- a/core/lib/Drupal/Core/Pager/PagerParameters.php
+++ b/core/lib/Drupal/Core/Pager/PagerParameters.php
@@ -36,7 +36,7 @@ public function getQueryParameters() {
     $request = $this->requestStack->getCurrentRequest();
     if ($request) {
       return UrlHelper::filterQueryParameters(
-        $request->query->all(), ['page']
+        $request->query->all(), ['page', 'ajax_page_state']
       );
     }
     return [];
diff --git a/core/modules/views/src/Controller/ViewAjaxController.php b/core/modules/views/src/Controller/ViewAjaxController.php
index 67caeb62b9c28417de0182eb54882b0eea84584b..37bd261b527acd4ef879538420ff44b12a4494fc 100644
--- a/core/modules/views/src/Controller/ViewAjaxController.php
+++ b/core/modules/views/src/Controller/ViewAjaxController.php
@@ -162,17 +162,21 @@ public function ajaxView(Request $request) {
           $this->currentPath->setPath('/' . ltrim($path, '/'), $request);
         }
 
+        // Create a clone of the request object to avoid mutating the request
+        // object stored in the request stack.
+        $request_clone = clone $request;
+
         // 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();
-        $query_all = $request->query->all();
-        $request->query->replace($request_all + $query_all);
+        $param_union = $request_clone->request->all() + $request_clone->query->all();
+        unset($param_union['ajax_page_state']);
+        $request_clone->query->replace($param_union);
 
         // Overwrite the destination.
         // @see the redirect.destination service.
-        $origin_destination = $path;
+        $origin_destination = $request_clone->getBasePath() . '/' . ltrim($path ?? '/', '/');
 
-        $used_query_parameters = $request->query->all();
+        $used_query_parameters = $request_clone->query->all();
         $query = UrlHelper::buildQuery($used_query_parameters);
         if ($query != '') {
           $origin_destination .= '?' . $query;
diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php
index af976a24569cb1907ab8088f834dcb085d2f4e43..674e12ba62d1fe62987814ea942db87ca11a6b1b 100644
--- a/core/modules/views/src/ViewExecutable.php
+++ b/core/modules/views/src/ViewExecutable.php
@@ -705,7 +705,7 @@ public function getExposedInput() {
 
       $this->exposed_input = \Drupal::request()->query->all();
       // unset items that are definitely not our input:
-      foreach (['page', 'q'] as $key) {
+      foreach (['page', 'q', 'ajax_page_state'] as $key) {
         if (isset($this->exposed_input[$key])) {
           unset($this->exposed_input[$key]);
         }
diff --git a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
index d4a73743320da151f98a609b3f17c18ab9338a36..758a8a4676a983bbc1db19464cbca4c666b86c48 100644
--- a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
+++ b/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
@@ -100,6 +100,9 @@ public function testBasicPagination() {
     $link = $page->findLink('Go to page 3');
     $this->assertNoDuplicateAssetsOnPage();
 
+    // 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->clickLink('Go to page 3');
     $session_assert->assertWaitOnAjaxRequest();
     $rows = $page->findAll('css', 'tbody tr');
diff --git a/core/modules/views/tests/src/FunctionalJavascript/RedirectAjaxTest.php b/core/modules/views/tests/src/FunctionalJavascript/RedirectAjaxTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c07f72446b11f9bae00c8e03a2c402bf2aa62e01
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavascript/RedirectAjaxTest.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
+use Drupal\Tests\node\Traits\NodeCreationTrait;
+
+/**
+ * Tests that the redirects work with Ajax enabled views.
+ *
+ * @group views
+ */
+class RedirectAjaxTest extends WebDriverTestBase {
+
+  use ContentTypeCreationTrait;
+  use NodeCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['node', 'views'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    // Enable AJAX on the /admin/content View.
+    \Drupal::configFactory()->getEditable('views.view.content')
+      ->set('display.default.display_options.use_ajax', TRUE)
+      ->save();
+
+    $this->createContentType(['type' => 'article']);
+    $this->createNode(['title' => 'Tiny paws and playful mews, kittens bring joy in every hue', 'type' => 'article']);
+
+    $user = $this->drupalCreateUser([
+      'access content overview',
+      'administer nodes',
+      'bypass node access',
+    ]);
+    $this->drupalLogin($user);
+  }
+
+  /**
+   * Ensures that redirects work with ajax.
+   */
+  public function testRedirectWithAjax() {
+    $this->drupalGet('admin/content');
+    $original_url = $this->getSession()->getCurrentUrl();
+
+    $this->assertSession()->pageTextContains('Tiny paws and playful mews, kittens bring joy in every hue');
+
+    $this->submitForm(['title' => 'Kittens'], 'Filter');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertSession()->pageTextContains('Tiny paws and playful mews, kittens bring joy in every hue');
+    $this->getSession()->getPage()->find('css', '.dropbutton-toggle button')->click();
+    $this->clickLink('Delete');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertEquals('Are you sure you want to delete the content item Tiny paws and playful mews, kittens bring joy in every hue?', $this->assertSession()->waitForElement('css', '.ui-dialog-title')->getText());
+    $this->getSession()->getPage()->find('css', '.ui-dialog-buttonset')->pressButton('Delete');
+
+    $this->assertSession()->pageTextContains('The Article Tiny paws and playful mews, kittens bring joy in every hue has been deleted.');
+    $this->assertStringStartsWith($original_url, $this->getSession()->getCurrentUrl());
+    $this->assertSession()->responseContains('core/modules/views/css/views.module.css');
+  }
+
+}
diff --git a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php
index a455b74257dd26cf861d6662927c1769ee2e2ba3..1d07ee94f38c6aabaf758c83eb68f266638cf03a 100644
--- a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php
+++ b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php
@@ -195,7 +195,7 @@ public function testAjaxView() {
 
     $this->redirectDestination->expects($this->atLeastOnce())
       ->method('set')
-      ->with('/test-page?ajax_page_state=drupal.settings%5B%5D&type=article');
+      ->with('/test-page?type=article');
     $this->currentPath->expects($this->once())
       ->method('setPath')
       ->with('/test-page', $request);
@@ -224,7 +224,7 @@ public function testAjaxViewViewPathNoSlash() {
 
     $this->redirectDestination->expects($this->atLeastOnce())
       ->method('set')
-      ->with('test-page?ajax_page_state=drupal.settings%5B%5D&type=article');
+      ->with('/test-page?type=article');
     $this->currentPath->expects($this->once())
       ->method('setPath')
       ->with('/test-page');