Cors.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <?php
  2. namespace app\common\middleware;
  3. use Closure;
  4. use think\Response;
  5. /**
  6. * 全局跨域处理
  7. */
  8. class Cors
  9. {
  10. /**
  11. * 生成统一的跨域响应头。
  12. *
  13. * 除中间件正常响应外,shutdown() 这类提前终止的响应也需要复用,
  14. * 否则浏览器会把真实的登录/权限错误误报为 CORS 错误。
  15. */
  16. public static function headers($request): array
  17. {
  18. $origin = $request->header('origin', '');
  19. $origin = trim(str_replace(["\r", "\n"], '', $origin));
  20. $requestedHeaders = $request->header('access-control-request-headers', '');
  21. $requestedHeaders = trim(str_replace(["\r", "\n"], '', $requestedHeaders));
  22. $allowedHeaders = [
  23. 'Origin',
  24. 'X-Requested-With',
  25. 'Content-Type',
  26. 'Accept',
  27. 'Authorization',
  28. 'AuthToken',
  29. 'SessionId',
  30. 'Lang',
  31. 'Accept-Language',
  32. 'ClientId',
  33. 'Cid',
  34. 'X-Im-AppId',
  35. 'X-Im-Sign',
  36. 'X-Im-TimeStamp',
  37. ];
  38. if ($requestedHeaders !== '') {
  39. $allowedHeaders[] = $requestedHeaders;
  40. }
  41. $headers = [
  42. 'Access-Control-Allow-Origin' => $origin === '' ? '*' : $origin,
  43. 'Access-Control-Allow-Methods' => 'GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD',
  44. 'Access-Control-Allow-Headers' => implode(', ', $allowedHeaders),
  45. 'Access-Control-Expose-Headers' => '*',
  46. 'Access-Control-Max-Age' => '86400',
  47. ];
  48. if ($origin !== '') {
  49. $headers['Access-Control-Allow-Credentials'] = 'true';
  50. $headers['Vary'] = 'Origin';
  51. }
  52. if ($request->header('access-control-request-private-network') === 'true') {
  53. $headers['Access-Control-Allow-Private-Network'] = 'true';
  54. }
  55. return $headers;
  56. }
  57. public function handle($request, Closure $next)
  58. {
  59. $headers = self::headers($request);
  60. if (strtoupper($request->method()) === 'OPTIONS') {
  61. return Response::create('', 'html', 204)->header($headers);
  62. }
  63. return $next($request)->header($headers);
  64. }
  65. }