Today I was building a Laravel app where I needed to query the back-
end for vehicles. The URL included the "make" of the vehicle as an encoded URL segment, and Laravel in turn would provide the models.
// routes/web.php
Route::get('/vehicles/{make}', function ($make) {
$models = VehicleModels::select()
->where('make', $make)
->get();
return view('models', ['models' => $models]);
});
I wanted to see what models "Toyota/Scion" had, but this didn't work when I navigated to /vehicles/Toyota%2FScion
. I instead got a 404 error because Laravel was interpreting this path as /vehicles/Toyota/Scion
. According to Laravel team members in the GitHub issue tracker, this is the intended behavior and there are no plans to change it. Bummer.
Fortunately, Andrew Finnell proposed a relatively painless solution: double-encode the URL segment, then decode it on the server. Here's what that looks like:
// Original code for generating link:
$link = '/vehicles/' . urlencode('Toyota/Scion');
// New code that encodes url twice:
$link = '/vehicles/' . urlencode(urlencode('Toyota/Scion'));
// Now, we'll decode the route segment in the Laravel back-end:
Route::get('/vehicles/{make}', function ($make) {
$models = VehicleModels::select()
->where('make', urldecode($make))
->get();
return view('models', ['models' => $models]);
});
With this code, Laravel does not interpret the encoded forward slashes as new URL segments, which means I can successfully query the back-end for "Toyota/Scion" using the generated url /vehicles/Toyota%252FScion
.
Alternatively, if you wanted to encode the link using JavaScript on the front-end, you'd use the following code:
const link = `/vehicles/${encodeURIComponent(encodeURIComponent("Toyota/Scion"))}
Hopefully this post makes the solution more discoverable and saves you some frustration. I also saw recommendations for Base64 encoding and an older Laravel package that seems to solve the same problem, but I haven't tested these solutions personally.
Top comments (0)