Access-Control-Allow-Origin: * allows any website to access your resources. Always specify exact origins in production.
If you don't have access to configure Apache/Nginx, you can still send CORS headers from a PHP script. This is useful for shared hosting or when you need different CORS policies for different endpoints.
Important: As with all uses of the PHP header function, CORS headers must be sent before any output has been sent from the server. Call header() before any echo, print, or HTML output.
Tip: For production applications, consider using a PHP framework like Laravel, Symfony, or Slim which have built-in CORS middleware packages that handle all edge cases automatically.
<?php
// Allow from specific origin
header("Access-Control-Allow-Origin: https://example.com");
header("Vary: Origin");
// Your PHP code here
To allow multiple specific origins (issue #146):
<?php
$allowedOrigins = [
'https://example.com',
'https://app.example.com'
];
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
header("Vary: Origin");
}
// Your PHP code here
For APIs that use custom headers or methods like PUT/DELETE:
<?php
$allowedOrigins = [
'https://example.com',
'https://app.example.com'
];
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
// Validate origin
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
header("Vary: Origin");
}
// Set other CORS headers
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Max-Age: 86400");
http_response_code(204);
exit(0);
}
// Your API logic here
When using cookies or sessions, you must specify exact origins (wildcards are not allowed):
<?php
$allowedOrigins = [
'https://example.com',
'https://app.example.com'
];
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
// Validate origin
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
header("Vary: Origin");
}
// Handle preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Access-Control-Max-Age: 86400");
http_response_code(204);
exit(0);
}
// Your API logic here
Create a reusable function to simplify CORS configuration:
<?php
function handleCors($allowedOrigins = []) {
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
// Validate origin
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
header("Vary: Origin");
}
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
// Handle preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Max-Age: 86400");
http_response_code(204);
exit(0);
}
}
// Usage in your API
handleCors(['https://example.com', 'https://app.example.com']);
// Your API logic here
$data = ['message' => 'CORS enabled'];
header('Content-Type: application/json');
echo json_encode($data);
Only use for completely public resources:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
// Handle preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Max-Age: 86400");
http_response_code(204);
exit(0);
}
// Your public API logic here
For comprehensive testing instructions including curl commands, browser DevTools usage, and troubleshooting common CORS errors, see the CORS Testing Guide.
The content on this site stays fresh thanks to help from users like you! If you have suggestions or would like to contribute, fork us on GitHub.
Save 39% on CORS in Action with promotional code hossainco at manning.com/hossain