DEV Community 👩‍💻👨‍💻

Tyler Smith
Tyler Smith

Posted on

Handling url-encoded forwarded slashes in Laravel URLs

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]);
});
Enter fullscreen mode Exit fullscreen mode

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]);
});
Enter fullscreen mode Exit fullscreen mode

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"))}
Enter fullscreen mode Exit fullscreen mode

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.

Oldest comments (0)

DEV

Thank you.

 
Thanks for visiting DEV, we’ve worked really hard to cultivate this great community and would love to have you join us. If you’d like to create an account, you can sign up here.