Skip to content

Commit e96a821

Browse files
authored
Merge pull request #731 from ljbw/improve-url-handling
Improve URL handling with support for trailing slashes
2 parents ece822d + 43b5a43 commit e96a821

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/Response.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public function toResponse($request)
109109
[
110110
'component' => $this->component,
111111
'props' => $props,
112-
'url' => Str::start(Str::after($request->fullUrl(), $request->getSchemeAndHttpHost()), '/'),
112+
'url' => $this->getUrl($request),
113113
'version' => $this->version,
114114
'clearHistory' => $this->clearHistory,
115115
'encryptHistory' => $this->encryptHistory,
@@ -359,4 +359,29 @@ public function isPartial(Request $request): bool
359359
{
360360
return $request->header(Header::PARTIAL_COMPONENT) === $this->component;
361361
}
362+
363+
/**
364+
* Get the URL from the request (without the scheme and host) while preserving the trailing slash if it exists.
365+
*/
366+
protected function getUrl(Request $request): string
367+
{
368+
$url = Str::start(Str::after($request->fullUrl(), $request->getSchemeAndHttpHost()), '/');
369+
370+
$rawUri = Str::before($request->getRequestUri(), '?');
371+
372+
return Str::endsWith($rawUri, '/') ? $this->finishUrlWithTrailingSlash($url) : $url;
373+
}
374+
375+
/**
376+
* Ensure the URL has a trailing slash before the query string (if it exists).
377+
*/
378+
protected function finishUrlWithTrailingSlash(string $url): string
379+
{
380+
// Make sure the relative URL ends with a trailing slash and re-append the query string if it exists.
381+
$urlWithoutQueryWithTrailingSlash = Str::finish(Str::before($url, '?'), '/');
382+
383+
return str_contains($url, '?')
384+
? $urlWithoutQueryWithTrailingSlash.'?'.Str::after($url, '?')
385+
: $urlWithoutQueryWithTrailingSlash;
386+
}
362387
}

tests/ResponseTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,4 +827,52 @@ public function test_the_page_url_doesnt_double_up(): void
827827

828828
$this->assertSame('/subpath/product/123', $page->url);
829829
}
830+
831+
public function test_trailing_slashes_in_a_url_are_preserved(): void
832+
{
833+
$request = Request::create('/users/', 'GET');
834+
$request->headers->add(['X-Inertia' => 'true']);
835+
836+
$response = new Response('User/Index', []);
837+
$response = $response->toResponse($request);
838+
$page = $response->getData();
839+
840+
$this->assertSame('/users/', $page->url);
841+
}
842+
843+
public function test_trailing_slashes_in_a_url_with_query_parameters_are_preserved(): void
844+
{
845+
$request = Request::create('/users/?page=1&sort=name', 'GET');
846+
$request->headers->add(['X-Inertia' => 'true']);
847+
848+
$response = new Response('User/Index', []);
849+
$response = $response->toResponse($request);
850+
$page = $response->getData();
851+
852+
$this->assertSame('/users/?page=1&sort=name', $page->url);
853+
}
854+
855+
public function test_a_url_without_trailing_slash_is_resolved_correctly(): void
856+
{
857+
$request = Request::create('/users', 'GET');
858+
$request->headers->add(['X-Inertia' => 'true']);
859+
860+
$response = new Response('User/Index', []);
861+
$response = $response->toResponse($request);
862+
$page = $response->getData();
863+
864+
$this->assertSame('/users', $page->url);
865+
}
866+
867+
public function test_a_url_without_trailing_slash_and_query_parameters_is_resolved_correctly(): void
868+
{
869+
$request = Request::create('/users?page=1&sort=name', 'GET');
870+
$request->headers->add(['X-Inertia' => 'true']);
871+
872+
$response = new Response('User/Index', []);
873+
$response = $response->toResponse($request);
874+
$page = $response->getData();
875+
876+
$this->assertSame('/users?page=1&sort=name', $page->url);
877+
}
830878
}

0 commit comments

Comments
 (0)