Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the principle of handling OPTIONS requests in Laravel

2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

What is the principle of dealing with OPTIONS requests in Laravel? aiming at this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.

1. Problem description

The mechanism by which Laravel handles requests in OPTIONS mode is a mystery.

Suppose the URL we request is http://localhost:8080/api/test and the request method is OPTIONS.

If the requested URL does not have a request in any other way (such as GET or POST), an error of 404 NOT FOUND is returned.

If there is a request with the same URL, a successful response with a status code of200 will be returned without any additional content.

For example, if the following definition exists in the routing file routes/api.php, a successful response with a status code of 200 is returned when the / api/test request is called in OPTIONS mode.

Route::get ('/ test', 'TestController@test')

But at the same time, through the analysis, it can be found that the OPTIONS request will not enter the life cycle of the api routing file, at least the middleware bound to the routing file api where the GET request is located.

At this point, if you manually add an OPTIONS request, such as:

Route::get ('/ test', 'TestController@test'); Route::options (' / test', function (Request $request) {return response ('abc');})

At least the middleware of the api binding of the routing file where the GET request is located will be entered, and the request can be captured in the relevant handle function.

two。 Analyze the source code

By carefully looking at the source code of Laravel, I found some clues.

Around line 159 of the file vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php, the source code is as follows:

$routes = $this- > get ($request- > getMethod ()); / / First, we will see if we can find a matching route for this current request / / method. If we can, great, we can just return it so that it can be called / / by the consumer. Otherwise we will check for routes with another verb. $route = $this- > matchAgainstRoutes ($routes, $request); if (! Is_null ($route) {return $route- > bind ($request);} / / If no route was found we will now check if a matching route is specified by / / another HTTP verb. If it is we will need to throw a MethodNotAllowed and / / inform the user agent of which HTTP verb it should use for this route. $others = $this- > checkForAlternateVerbs ($request); if (count ($others) > 0) {return $this- > getRouteForMethods ($request, $others);} throw new NotFoundHttpException

The logic here is:

1. First of all, according to the current HTTP method (GET/POST/PUT/...) to find out whether there is a matching route, if there is (if (! Is_null ($route)) condition is established), very good, return directly after binding, and continue the subsequent call process.

two。 Otherwise, find the HTTP method that may match according to the route of $request (that is, URL match, but the HTTP request method is other), and if the count ($others) > 0 condition holds, proceed to $this- > getRouteForMethods ($request, $others); method

3. Otherwise, NotFoundHttpException is thrown, that is, the 404 NOT FOUND error mentioned above.

If you take step 2, jump to line 234 of the file and see that the function logic is:

Protected function getRouteForMethods ($request, array $methods) {if ($request- > method () = = 'OPTIONS') {return (new Route (' OPTIONS', $request- > path (), function () use ($methods) {return new Response (', 200, ['Allow' = > implode (',', $methods)]);})-> bind ($request);} $this- > methodNotAllowed ($methods);}

It is judged that if the request method is OPTIONS, a correct response with a status code of 200 is returned (but no header information is added), otherwise an error with a methodNotAllowed status code of 405 is returned (that is, the request method is not allowed).

Here, Laravel's HTTP request processing for OPTIONS has been fixed, so it's a bit of a headache. I don't know where to add code to handle the header of the OPTIONS request. The stupidest approach is to write an OPTIONS type route with the same name for every GET or POST request of a cross-domain request.

3. Solution.

There are two solutions, one is to add middleware, the other is to use wildcard routing matching scheme.

The overall idea is to add relevant OPTIONS information in the process of the system processing header requests.

3.1 Middleware solution

In the file app/Http/Kernel.php, there are two places where middleware can be defined.

The first is the total middleware $middleware, where any request will pass; the second is the group middleware middlewareGroups, which only passes through the corresponding group pattern on the route match.

This is the definition code for the total middleware $middleware:

Protected $middleware = [\ Illuminate\ Foundation\ Http\ Middleware\ CheckForMaintenanceMode::class,\ Illuminate\ Foundation\ Http\ Middleware\ ValidatePostSize::class,\ App\ Http\ Middleware\ TrimStrings::class,\ Illuminate\ Foundation\ Http\ Middleware\ ConvertEmptyStringsToNull::class,\ App\ Http\ Middleware\ TrustProxies::class,]

This is the definition code for the group middleware $middlewareGroups:

/ * The application's route middleware groups. * * @ var array * / protected $middlewareGroups = ['web' = > [\ App\ Http\ Middleware\ EncryptCookies::class,\ Illuminate\ Cookie\ Middleware\ AddQueuedCookiesToResponse::class,\ Illuminate\ Session\ Middleware\ StartSession::class, / /\ Illuminate\ Session\ Middleware\ AuthenticateSession::class,\ Illuminate\ View\ Middleware\ ShareErrorsFromSession::class \ App\ Http\ Middleware\ VerifyCsrfToken::class,\ Illuminate\ Routing\ Middleware\ SubstituteBindings::class,], 'api' = > [' throttle:60,1', 'bindings',\ Illuminate\ Session\ Middleware\ StartSession::class,],]

Because the group routing middleware does not enter until after the route matching process, the OPTIONS request mentioned in the previous experiment has been returned before it has passed the handle function of the middleware here.

So the middleware we added needs to be added to the $middleware array, not to the api group routing middleware.

Create a new PreflightResponse.php file under the app/Http/Middleware folder:

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report