Handling “XMLHttpRequest” OPTIONS Pre-flight Request in Laravel
Sometimes, when making AJAX requests to a server, the request seems to keep defaulting to “OPTIONS” as opposed to the “GET/POST/PUT/DELETE” you specified when creating your XMLHttpRequest.
This is roughly because of CORS and its security measures. When the request contains a custom header (sometimes even Authorization is considered as a custom header 😕) then the browser will automatically send a “pre-flight” OPTIONS request to the URL before sending the actual request. This is supposed to be a security measure. It basically sends the request to check that the target server has appropriate access control headers for the source domain and request.
The problem with this is, if you are using a framework like Laravel, and you are building your API and adhering to REST principles, chances are that you respond to specific HTTP request types.
Since the browser is sending an OPTIONS
request, it will always fail with a 404 Page Not Found
error. This can be very frustrating and I really just spent a good amount of time trying to fix this issue.
You will get an error like: “Response for preflight has invalid HTTP status code”
A Not-So-Boutique Solution
If you are using Laravel then it would be easy to solve this using a Middleware. Create a new Middleware in your Laravel (5.2) application app/Http/Middleware/PreflightResponse.php
<?phpnamespace App\Http\Middleware;use Closure;class PreflightResponse
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next )
{
if ($request->getMethod() === "OPTIONS") {
return response('');
}return $next($request);
}
}
Then in the app/Http/Kernel.php
file, add the Middleware you just created to the global middleware array
protected $middleware = [
Middleware\PreflightResponse::class,
// ...
];
What this does basically is allow the passage of all OPTIONS
request. Of course you could register it as a named middleware and apply it to single endpoints that may need this.
Thats all! Your Laravel application now correctly responds to AJAX preflight http requests with the OPTIONS method by sending a response with the status code 200. Your browser will verify the access control headers and will continue to send the actual AJAX request, as normal.