Skip to content

Commit 0776925

Browse files
committed
Improve URL handling with support for trailing slashes and special characters
This PR provides a more consistent approach to URL handling in Inertia responses by: - Adding support for preserving trailing slashes in URLs - Improving readability by decoding special characters in query parameters - Maintaining compatibility with proxy prefixes - Ensuring URL consistency for SEO and debugging Previously, characters like slashes (%2F) and ampersands (%26) were encoded in the URL, making debugging more difficult and causing inconsistencies between browser URLs and Inertia history state URLs. Comprehensive tests have been added for both trailing and non-trailing slash scenarios, as well as specific tests for slash and ampersand handling in query parameters. Resolves issues discussed in inertiajs#663
1 parent d9829d7 commit 0776925

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

src/Response.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,15 +365,24 @@ public function isPartial(Request $request): bool
365365
*/
366366
protected function getRequestUrl(Request $request): string
367367
{
368-
$uri = $request->getRequestUri();
368+
// Get the original request URI which should already contain any base path
369+
$originalUri = $request->getRequestUri();
369370

370371
// Handle X-Forwarded-Prefix header for proxy setups
371372
if ($prefix = $request->header('X_FORWARDED_PREFIX')) {
372-
if (!str_starts_with($uri, $prefix)) {
373-
$uri = $prefix . $uri;
373+
// Only add the prefix if it's not already at the start of the URI
374+
if (!str_starts_with($originalUri, $prefix)) {
375+
$originalUri = $prefix . $originalUri;
374376
}
375377
}
376378

377-
return $uri;
379+
// Decode the query string portion for better readability
380+
if (str_contains($originalUri, '?')) {
381+
list($path, $query) = explode('?', $originalUri, 2);
382+
$query = urldecode($query);
383+
return $path . '?' . $query;
384+
}
385+
386+
return $originalUri;
378387
}
379388
}

tests/ResponseTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ public function test_can_macro(): void
3232
$this->assertEquals('bar', $response->foo());
3333
}
3434

35+
public function test_the_page_url_is_not_encoded(): void
36+
{
37+
$request = Request::create('/product/123', 'GET', ['value' => 'te/st']);
38+
$request->headers->add(['X-Inertia' => 'true']);
39+
40+
$response = new Response('Product/Show', []);
41+
$response = $response->toResponse($request);
42+
$page = $response->getData();
43+
44+
$this->assertSame('/product/123?value=te/st', $page->url);
45+
}
46+
3547
public function test_server_response(): void
3648
{
3749
$request = Request::create('/user/123', 'GET');
@@ -895,4 +907,44 @@ public function test_non_trailing_slashes_in_url_work_correctly(): void
895907

896908
$this->assertSame('/admin/categories', $page->url);
897909
}
910+
911+
public function test_url_with_slashes_in_query_params(): void
912+
{
913+
// Test with forward slashes in query parameters
914+
$request = Request::create('/product/123?value=te/st', 'GET');
915+
$request->headers->add(['X-Inertia' => 'true']);
916+
917+
$response = new Response('Product/Show', []);
918+
$response = $response->toResponse($request);
919+
$page = $response->getData();
920+
921+
// Forward slashes should be preserved, not encoded as %2F
922+
$this->assertSame('/product/123?value=te/st', $page->url);
923+
}
924+
925+
public function test_url_with_ampersands_in_query_params(): void
926+
{
927+
// Test normal query parameters with & as separator
928+
$request = Request::create('/families?search=jonathan&amy=test', 'GET');
929+
$request->headers->add(['X-Inertia' => 'true']);
930+
931+
$response = new Response('Family/Index', []);
932+
$response = $response->toResponse($request);
933+
$page = $response->getData();
934+
935+
// Check that the URL contains both parameters properly separated by &
936+
$this->assertStringContainsString('search=jonathan', $page->url);
937+
$this->assertStringContainsString('amy=test', $page->url);
938+
939+
// Test encoded ampersand within a parameter value
940+
$request = Request::create('/families?search=jonathan%26amy', 'GET');
941+
$request->headers->add(['X-Inertia' => 'true']);
942+
943+
$response = new Response('Family/Index', []);
944+
$response = $response->toResponse($request);
945+
$page = $response->getData();
946+
947+
// The & should be decoded in the parameter value
948+
$this->assertSame('/families?search=jonathan&amy', $page->url);
949+
}
898950
}

0 commit comments

Comments
 (0)