
PHP跨域资源共享CORS配置前后端分离架构中跨域问题是必须处理的。CORS是浏览器允许跨域请求的机制。今天说说PHP中CORS的配置。基础的CORS响应头。phpheader(Access-Control-Allow-Origin: *);header(Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS);header(Access-Control-Allow-Headers: Content-Type, Authorization);header(Access-Control-Max-Age: 86400);if ($_SERVER[REQUEST_METHOD] OPTIONS) {http_response_code(204);exit;}?带权限控制的CORS。phpclass CorsMiddleware{private array $allowedOrigins;private array $allowedMethods;private array $allowedHeaders;public function __construct(array $allowedOrigins [*],array $allowedMethods [GET, POST, PUT, DELETE, OPTIONS],array $allowedHeaders [Content-Type, Authorization, X-Requested-With]) {$this-allowedOrigins $allowedOrigins;$this-allowedMethods $allowedMethods;$this-allowedHeaders $allowedHeaders;}public function handle(): void{$origin $_SERVER[HTTP_ORIGIN] ?? *;if (in_array(*, $this-allowedOrigins)) {header(Access-Control-Allow-Origin: *);} elseif (in_array($origin, $this-allowedOrigins)) {header(Access-Control-Allow-Origin: $origin);header(Vary: Origin);}header(Access-Control-Allow-Methods: . implode(, , $this-allowedMethods));header(Access-Control-Allow-Headers: . implode(, , $this-allowedHeaders));header(Access-Control-Max-Age: 86400);if ($_SERVER[REQUEST_METHOD] OPTIONS) {http_response_code(204);exit;}}public function addOrigin(string $origin): void{if (!in_array($origin, $this-allowedOrigins)) {$this-allowedOrigins[] $origin;}}}$cors new CorsMiddleware([http://localhost:3000, https://myapp.com]);$cors-addOrigin(https://admin.myapp.com);$cors-handle();?处理凭证Cookie的CORS。phpheader(Access-Control-Allow-Origin: https://myapp.com);header(Access-Control-Allow-Credentials: true);header(Access-Control-Allow-Methods: GET, POST);header(Access-Control-Allow-Headers: Content-Type);// 使用凭证时Access-Control-Allow-Origin不能是*// 必须明确指定源?自定义请求头的CORS。php$allowedHeaders [Content-Type, Authorization, X-Custom-Header, X-Request-Id];header(Access-Control-Allow-Headers: . implode(, , $allowedHeaders));// 也可以在响应中暴露自定义头给前端header(Access-Control-Expose-Headers: X-Total-Count, X-Request-Id);?CORS中间件的完整实现。phpclass CorsConfig{private static array $config [allowed_origins [*],allowed_methods [GET, POST, PUT, DELETE, PATCH, OPTIONS],allowed_headers [Content-Type, Authorization, X-Requested-With, Accept],exposed_headers [X-Total-Count, X-Request-Id],max_age 86400,allow_credentials false,];public static function configure(array $config): void{self::$config array_merge(self::$config, $config);}public static function apply(): void{$origin $_SERVER[HTTP_ORIGIN] ?? *;if (self::$config[allow_credentials]) {header(Access-Control-Allow-Origin: . $origin);header(Access-Control-Allow-Credentials: true);} elseif (in_array(*, self::$config[allowed_origins])) {header(Access-Control-Allow-Origin: *);} elseif (in_array($origin, self::$config[allowed_origins])) {header(Access-Control-Allow-Origin: . $origin);}header(Access-Control-Allow-Methods: . implode(, , self::$config[allowed_methods]));header(Access-Control-Allow-Headers: . implode(, , self::$config[allowed_headers]));if (!empty(self::$config[exposed_headers])) {header(Access-Control-Expose-Headers: . implode(, , self::$config[exposed_headers]));}header(Access-Control-Max-Age: . self::$config[max_age]);if ($_SERVER[REQUEST_METHOD] OPTIONS) {http_response_code(204);exit;}}}CorsConfig::configure([allowed_origins [http://localhost:3000],allow_credentials true,]);CorsConfig::apply();?CORS是前后端分离必须处理的问题。开发环境可以宽放一些生产环境要严格控制允许的源。使用凭证时Access-Control-Allow-Origin不能是*。OPTIONS预检请求要快速响应不要做耗时操作。