This PHP snippet is to fulfill the pre-flight requirement for Cross Origin Resource Sharing (CORS) so browsers will access a resource from another domain to your server. This is useful for any APIs (restful or not), or any resource that will be called remotely. You can basically copy and paste this code.
Brief explanation:
- Before doing the actual request, the browser will first do a OPTIONS request first.
- Your API needs to provide response with proper headers below (per below).
- Browser only needs headers, so you can exit the script after proper headers are in-place.
- If response is incorrect, or incomplete, it will have errors.
- Browser then will do the real request, so you still create all the headers and let the script continue.
Other Hints:
- Do NOT try to echo or print_r before this as you are trying to send headers!
- It is tricky to find where to put this in a bigger / complex script, so be careful where you put it or else it may be too late to send these headers.
- You can use Postman to create a sample pre-flight request for testing / debugging.
- Common errors in Chrome:
- “Failed to load [Endpoint URL]: Response to preflight request doesn’t pass access control check: No “Access-Control-Allow-Origin” header is present on the requested resource. Origin ‘[Endpoint URL]’ is therefore not allowed access.” means the Access-Control-Allow-Origin is missing or wrong.
- “Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.” meaning “Access-Control-Allow-Headers” is missing or wrong.
- You need both even for the OPTIONS request
More reading if interested: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
PHP Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //Cross Origin Resource Sharing (CORS) - Pre-flight and headers PHP response for the browser will proceed if (isset($_SERVER['HTTP_ORIGIN']) || $_SERVER['REQUEST_METHOD'] == 'OPTIONS') { $http_origin = $_SERVER['HTTP_ORIGIN']; //$remoteOrigins is an array with permitted domains, dont forget https:// or http:// and port #s, if any if (in_array($http_origin, Config::$remoteOrigins)) { header("Access-Control-Allow-Origin: " . $http_origin); header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Methods: GET,PUT,POST,DELETE,PATCH,OPTIONS"); header("Access-Control-Allow-Headers: Authorization,Origin,X-Requested-With,Content-Type,Accept,Referrer"); } if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { exit; } } |