0 追蹤者

類別 yii\filters\Cors

繼承關係yii\filters\Cors » yii\base\ActionFilter » yii\base\Behavior » yii\base\BaseObject
實作介面yii\base\Configurable
自版本起可用2.0
原始碼 https://github.com/yiisoft/yii2/blob/master/framework/filters/Cors.php

Cors 過濾器實作了 跨來源資源共用

請務必仔細閱讀 CORS 的作用和不作用。CORS 不會保護您的 API,但允許開發人員授與對第三方程式碼的存取權限(來自外部網域的 ajax 呼叫)。

您可以透過將 CORS 過濾器作為行為附加到控制器或模組來使用它,如下所示:

public function behaviors()
{
    return [
        'corsFilter' => [
            'class' => \yii\filters\Cors::class,
        ],
    ];
}

CORS 過濾器可以專門用於限制參數,例如:MDN CORS 資訊

public function behaviors()
{
    return [
        'corsFilter' => [
            'class' => \yii\filters\Cors::class,
            'cors' => [
                // restrict access to
                'Origin' => ['http://www.myserver.com', 'https://www.myserver.com'],
                // Allow only POST and PUT methods
                'Access-Control-Request-Method' => ['POST', 'PUT'],
                // Allow only headers 'X-Wsse'
                'Access-Control-Request-Headers' => ['X-Wsse'],
                // Allow credentials (cookies, authorization headers, etc.) to be exposed to the browser
                'Access-Control-Allow-Credentials' => true,
                // Allow OPTIONS caching
                'Access-Control-Max-Age' => 3600,
                // Allow the X-Pagination-Current-Page header to be exposed to the browser.
                'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
            ],

        ],
    ];
}

有關如何將 CORS 過濾器添加到控制器的更多資訊,請參閱 REST 控制器指南

公開屬性

隱藏繼承的屬性

屬性 類型 描述 定義於
$actions 陣列 為特定動作定義特定的 CORS 規則 yii\filters\Cors
$cors 陣列 為 CORS 請求處理的基本標頭。 yii\filters\Cors
$except 陣列 此過濾器不應套用的動作 ID 清單。 yii\base\ActionFilter
$only 陣列 此過濾器應套用的動作 ID 清單。 yii\base\ActionFilter
$owner yii\base\Component|null 此行為的擁有者 yii\base\Behavior
$request yii\web\Request|null 當前請求。 yii\filters\Cors
$response yii\web\Response|null 要發送的回應。 yii\filters\Cors

公開方法

隱藏繼承的方法

方法 描述 定義於
__call() 呼叫不是類別方法的具名方法。 yii\base\BaseObject
__construct() 建構子。 yii\base\BaseObject
__get() 傳回物件屬性的值。 yii\base\BaseObject
__isset() 檢查屬性是否已設定,即已定義且非 null。 yii\base\BaseObject
__set() 設定物件屬性的值。 yii\base\BaseObject
__unset() 將物件屬性設定為 null。 yii\base\BaseObject
addCorsHeaders() 將 CORS 標頭新增至回應。 yii\filters\Cors
afterAction() 此方法在動作執行後立即調用。 yii\base\ActionFilter
afterFilter() yii\base\ActionFilter
attach() 將行為物件附加到元件。 yii\base\ActionFilter
beforeAction() 此方法在動作即將執行之前調用(在所有可能的過濾器之後)。您可以覆寫此方法以執行動作的最後一分鐘準備。 yii\filters\Cors
beforeFilter() yii\base\ActionFilter
canGetProperty() 傳回指示屬性是否可讀取的值。 yii\base\BaseObject
canSetProperty() 傳回指示屬性是否可設定的值。 yii\base\BaseObject
className() 傳回此類別的完整命名空間名稱。 yii\base\BaseObject
detach() 從元件中分離行為物件。 yii\base\ActionFilter
events() $owner 的事件宣告事件處理常式。 yii\base\Behavior
extractHeaders() 從請求中提取 CORS 標頭。 yii\filters\Cors
hasMethod() 傳回指示是否已定義方法的值。 yii\base\BaseObject
hasProperty() 傳回指示是否已定義屬性的值。 yii\base\BaseObject
init() 初始化物件。 yii\base\BaseObject
overrideDefaultSettings() 覆寫特定動作的設定。 yii\filters\Cors
prepareHeaders() 為每個 CORS 標頭建立特定的回應。 yii\filters\Cors

保護方法

隱藏繼承的方法

方法 描述 定義於
getActionId() 透過將 yii\base\Action::$uniqueId 轉換為相對於模組的 ID 來傳回動作 ID。 yii\base\ActionFilter
headerize() 將任何字串(包括帶有 HTTP 前綴的 php 標頭)轉換為標頭格式。 yii\filters\Cors
headerizeToPhp() 將任何字串(包括帶有 HTTP 前綴的 php 標頭)轉換為標頭格式。 yii\filters\Cors
isActive() 傳回指示過濾器對於給定動作是否為活動狀態的值。 yii\base\ActionFilter
prepareAllowHeaders() 處理經典 CORS 請求以避免重複程式碼。 yii\filters\Cors

屬性詳細資訊

隱藏繼承的屬性

$actions 公開屬性

為特定動作定義特定的 CORS 規則

public array $actions = []
$cors 公開屬性

為 CORS 請求處理的基本標頭。

public array $cors = [
    
'Origin' => [
        
'*',
    ],
    
'Access-Control-Request-Method' => [
        
'GET',
        
'POST',
        
'PUT',
        
'PATCH',
        
'DELETE',
        
'HEAD',
        
'OPTIONS',
    ],
    
'Access-Control-Request-Headers' => [
        
'*',
    ],
    
'Access-Control-Allow-Credentials' => null,
    
'Access-Control-Max-Age' => 86400,
    
'Access-Control-Expose-Headers' => [],
]
$request 公開屬性

當前請求。如果未設定,將會使用 request 應用程式組件。

$response 公開屬性

要發送的回應。如果未設定,將會使用 response 應用程式組件。

方法詳細資訊

隱藏繼承的方法

__call() 公開方法

定義於: yii\base\BaseObject::__call()

呼叫不是類別方法的具名方法。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當調用未知方法時會被隱式呼叫。

public mixed __call ( $name, $params )
$name string

方法名稱

$params 陣列

方法參數

return mixed

方法回傳值

throws yii\base\UnknownMethodException

當呼叫未知方法時

                public function __call($name, $params)
{
    throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}

            
__construct() 公開方法

定義於: yii\base\BaseObject::__construct()

建構子。

預設實作會做兩件事

  • 使用給定的組態 $config 初始化物件。
  • 呼叫 init()

如果子類別中覆寫了此方法,建議

  • 建構子的最後一個參數是一個組態陣列,就像此處的 $config 一樣。
  • 在建構子的結尾呼叫父類別的實作。
public void __construct ( $config = [] )
$config 陣列

將用於初始化物件屬性的名稱-值配對

                public function __construct($config = [])
{
    if (!empty($config)) {
        Yii::configure($this, $config);
    }
    $this->init();
}

            
__get() 公開方法

定義於: yii\base\BaseObject::__get()

傳回物件屬性的值。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 $value = $object->property; 時會被隱式呼叫。

另請參閱 __set()

public mixed __get ( $name )
$name string

屬性名稱

return mixed

屬性值

throws yii\base\UnknownPropertyException

如果屬性未定義

throws yii\base\InvalidCallException

如果屬性為唯寫

                public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    } elseif (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    }
    throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}

            
__isset() 公開方法

定義於: yii\base\BaseObject::__isset()

檢查屬性是否已設定,即已定義且非 null。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 isset($object->property) 時會被隱式呼叫。

請注意,如果屬性未定義,將會回傳 false。

另請參閱 https://php.dev.org.tw/manual/en/function.isset.php

public boolean __isset ( $name )
$name string

屬性名稱或事件名稱

return boolean

具名屬性是否已設定(非 null)。

                public function __isset($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter() !== null;
    }
    return false;
}

            
__set() 公開方法

定義於: yii\base\BaseObject::__set()

設定物件屬性的值。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 $object->property = $value; 時會被隱式呼叫。

另請參閱 __get()

public void __set ( $name, $value )
$name string

屬性名稱或事件名稱

$value mixed

屬性值

throws yii\base\UnknownPropertyException

如果屬性未定義

throws yii\base\InvalidCallException

如果屬性為唯讀

                public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}

            
__unset() 公開方法

定義於: yii\base\BaseObject::__unset()

將物件屬性設定為 null。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 unset($object->property) 時會被隱式呼叫。

請注意,如果屬性未定義,此方法將不會執行任何操作。 如果屬性為唯讀,它將拋出例外。

另請參閱 https://php.dev.org.tw/manual/en/function.unset.php

public void __unset ( $name )
$name string

屬性名稱

throws yii\base\InvalidCallException

如果屬性為唯讀。

                public function __unset($name)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter(null);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
    }
}

            
addCorsHeaders() 公開方法

將 CORS 標頭新增至回應。

public void addCorsHeaders ( $response, $headers )
$response yii\web\Response
$headers 陣列

已計算的 CORS 標頭

                public function addCorsHeaders($response, $headers)
{
    if (empty($headers) === false) {
        $responseHeaders = $response->getHeaders();
        foreach ($headers as $field => $value) {
            $responseHeaders->set($field, $value);
        }
    }
}

            
afterAction() 公開方法

定義於: yii\base\ActionFilter::afterAction()

此方法在動作執行後立即調用。

您可以覆寫此方法,為 action 執行一些後處理。

public mixed afterAction ( $action, $result )
$action yii\base\Action

剛執行的 action。

$result mixed

action 執行結果

return mixed

已處理的 action 結果。

                public function afterAction($action, $result)
{
    return $result;
}

            
afterFilter() 公開方法
public void afterFilter ( $event )
$event yii\base\ActionEvent

                public function afterFilter($event)
{
    $event->result = $this->afterAction($event->action, $event->result);
    $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
}

            
attach() 公開方法

定義於: yii\base\ActionFilter::attach()

將行為物件附加到元件。

預設實作將設定 $owner 屬性,並附加在 events() 中宣告的事件處理器。 如果您覆寫此方法,請確保呼叫父類別的實作。

public void attach ( $owner )
$owner yii\base\Component

此行為要附加到的組件。

                public function attach($owner)
{
    $this->owner = $owner;
    $owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
}

            
beforeAction() 公開方法

此方法在動作即將執行之前調用(在所有可能的過濾器之後)。您可以覆寫此方法以執行動作的最後一分鐘準備。

public boolean beforeAction ( $action )
$action yii\base\Action

要執行的 action。

return boolean

是否應繼續執行 action。

                public function beforeAction($action)
{
    $this->request = $this->request ?: Yii::$app->getRequest();
    $this->response = $this->response ?: Yii::$app->getResponse();
    $this->overrideDefaultSettings($action);
    $requestCorsHeaders = $this->extractHeaders();
    $responseCorsHeaders = $this->prepareHeaders($requestCorsHeaders);
    $this->addCorsHeaders($this->response, $responseCorsHeaders);
    if ($this->request->isOptions && $this->request->headers->has('Access-Control-Request-Method')) {
        // it is CORS preflight request, respond with 200 OK without further processing
        $this->response->setStatusCode(200);
        return false;
    }
    return true;
}

            
beforeFilter() 公開方法
public void beforeFilter ( $event )
$event yii\base\ActionEvent

                public function beforeFilter($event)
{
    if (!$this->isActive($event->action)) {
        return;
    }
    $event->isValid = $this->beforeAction($event->action);
    if ($event->isValid) {
        // call afterFilter only if beforeFilter succeeds
        // beforeFilter and afterFilter should be properly nested
        $this->owner->on(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter'], null, false);
    } else {
        $event->handled = true;
    }
}

            
canGetProperty() 公開方法

定義於: yii\base\BaseObject::canGetProperty()

傳回指示屬性是否可讀取的值。

如果屬性是可讀取的:

  • 類別具有與指定名稱相關聯的 getter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

另請參閱 canSetProperty()

public boolean canGetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可以讀取

                public function canGetProperty($name, $checkVars = true)
{
    return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
}

            
canSetProperty() 公開方法

定義於: yii\base\BaseObject::canSetProperty()

傳回指示屬性是否可設定的值。

如果屬性是可寫入的:

  • 類別具有與指定名稱相關聯的 setter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

另請參閱 canGetProperty()

public boolean canSetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可以寫入

                public function canSetProperty($name, $checkVars = true)
{
    return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
}

            
className() 公開靜態方法
自 2.0.14 版本起已過時。 在 PHP >=5.5 上,請改用 ::class

定義於: yii\base\BaseObject::className()

傳回此類別的完整命名空間名稱。

public static string className ( )
return string

此類別的完整限定名稱。

                public static function className()
{
    return get_called_class();
}

            
detach() 公開方法

定義於: yii\base\ActionFilter::detach()

從元件中分離行為物件。

預設實作將取消設定 $owner 屬性,並分離在 events() 中宣告的事件處理器。 如果您覆寫此方法,請確保呼叫父類別的實作。

public void detach ( )

                public function detach()
{
    if ($this->owner) {
        $this->owner->off(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
        $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
        $this->owner = null;
    }
}

            
events() 公開方法

定義於: yii\base\Behavior::events()

$owner 的事件宣告事件處理常式。

子類別可以覆寫此方法,以宣告應將哪些 PHP 回呼附加到 $owner 組件的事件。

當行為附加到擁有者時,回呼將會附加到 $owner 的事件; 當行為從組件分離時,它們將從事件中分離。

回呼可以是以下任何一種

  • 此行為中的方法:'handleClick',等效於 [$this, 'handleClick']
  • 物件方法:[$object, 'handleClick']
  • 靜態方法:['Page', 'handleClick']
  • 匿名函式:function ($event) { ... }

以下是一個範例

[
    Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
    Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
]
public array events ( )
return 陣列

事件(陣列鍵)和對應的事件處理器方法(陣列值)。

                public function events()
{
    return [];
}

            
extractHeaders() 公開方法

從請求中提取 CORS 標頭。

public array extractHeaders ( )
return 陣列

要處理的 CORS 標頭

                public function extractHeaders()
{
    $headers = [];
    foreach (array_keys($this->cors) as $headerField) {
        $serverField = $this->headerizeToPhp($headerField);
        $headerData = isset($_SERVER[$serverField]) ? $_SERVER[$serverField] : null;
        if ($headerData !== null) {
            $headers[$headerField] = $headerData;
        }
    }
    return $headers;
}

            
getActionId() protected method (自 2.0.7 版本起可用)

定義於: yii\base\ActionFilter::getActionId()

透過將 yii\base\Action::$uniqueId 轉換為相對於模組的 ID 來傳回動作 ID。

protected string getActionId ( $action )
$action yii\base\Action

                protected function getActionId($action)
{
    if ($this->owner instanceof Module) {
        $mid = $this->owner->getUniqueId();
        $id = $action->getUniqueId();
        if ($mid !== '' && strpos($id, $mid) === 0) {
            $id = substr($id, strlen($mid) + 1);
        }
    } else {
        $id = $action->id;
    }
    return $id;
}

            
hasMethod() 公開方法

定義於: yii\base\BaseObject::hasMethod()

傳回指示是否已定義方法的值。

預設實作是對 php 函式 method_exists() 的呼叫。 當您實作 php 魔術方法 __call() 時,您可以覆寫此方法。

public boolean hasMethod ( $name )
$name string

方法名稱

return boolean

方法是否已定義

                public function hasMethod($name)
{
    return method_exists($this, $name);
}

            
hasProperty() 公開方法

定義於: yii\base\BaseObject::hasProperty()

傳回指示是否已定義屬性的值。

如果符合以下任一條件,則定義了屬性:

  • 類別具有與指定名稱相關聯的 getter 或 setter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

另請參閱

public boolean hasProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否已定義

                public function hasProperty($name, $checkVars = true)
{
    return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
}

            
headerize() protected method

將任何字串(包括帶有 HTTP 前綴的 php 標頭)轉換為標頭格式。

範例

  • X-PINGOTHER -> X-Pingother
  • X_PINGOTHER -> X-Pingother
protected string headerize ( $string )
$string string

要轉換的字串

return string

“標頭”格式的結果

                protected function headerize($string)
{
    $headers = preg_split('/[\\s,]+/', $string, -1, PREG_SPLIT_NO_EMPTY);
    $headers = array_map(function ($element) {
        return str_replace(' ', '-', ucwords(strtolower(str_replace(['_', '-'], [' ', ' '], $element))));
    }, $headers);
    return implode(', ', $headers);
}

            
headerizeToPhp() protected method

將任何字串(包括帶有 HTTP 前綴的 php 標頭)轉換為標頭格式。

範例

  • X-Pingother -> HTTP_X_PINGOTHER
  • X PINGOTHER -> HTTP_X_PINGOTHER
protected string headerizeToPhp ( $string )
$string string

要轉換的字串

return string

“php $_SERVER 標頭”格式的結果

                protected function headerizeToPhp($string)
{
    return 'HTTP_' . strtoupper(str_replace([' ', '-'], ['_', '_'], $string));
}

            
init() 公開方法

定義於: yii\base\BaseObject::init()

初始化物件。

在物件以給定組態初始化後,此方法會在建構子的結尾被調用。

public void init ( )

                public function init()
{
}

            
isActive() protected method

定義於: yii\base\ActionFilter::isActive()

傳回指示過濾器對於給定動作是否為活動狀態的值。

protected boolean isActive ( $action )
$action yii\base\Action

正在篩選的 action

return boolean

篩選器是否對給定的 action 處於活動狀態。

                protected function isActive($action)
{
    $id = $this->getActionId($action);
    if (empty($this->only)) {
        $onlyMatch = true;
    } else {
        $onlyMatch = false;
        foreach ($this->only as $pattern) {
            if (StringHelper::matchWildcard($pattern, $id)) {
                $onlyMatch = true;
                break;
            }
        }
    }
    $exceptMatch = false;
    foreach ($this->except as $pattern) {
        if (StringHelper::matchWildcard($pattern, $id)) {
            $exceptMatch = true;
            break;
        }
    }
    return !$exceptMatch && $onlyMatch;
}

            
overrideDefaultSettings() 公開方法

覆寫特定動作的設定。

public void overrideDefaultSettings ( $action )
$action yii\base\Action

要覆寫的 action 設定

                public function overrideDefaultSettings($action)
{
    if (isset($this->actions[$action->id])) {
        $actionParams = $this->actions[$action->id];
        $actionParamsKeys = array_keys($actionParams);
        foreach ($this->cors as $headerField => $headerValue) {
            if (in_array($headerField, $actionParamsKeys)) {
                $this->cors[$headerField] = $actionParams[$headerField];
            }
        }
    }
}

            
prepareAllowHeaders() protected method

處理經典 CORS 請求以避免重複程式碼。

protected void prepareAllowHeaders ( $type, $requestHeaders, &$responseHeaders )
$type string

我們將處理的標頭類型

$requestHeaders 陣列

用戶端請求的 CORS 標頭

$responseHeaders 陣列

傳送至用戶端的 CORS 回應標頭

                protected function prepareAllowHeaders($type, $requestHeaders, &$responseHeaders)
{
    $requestHeaderField = 'Access-Control-Request-' . $type;
    $responseHeaderField = 'Access-Control-Allow-' . $type;
    if (!isset($requestHeaders[$requestHeaderField], $this->cors[$requestHeaderField])) {
        return;
    }
    if (in_array('*', $this->cors[$requestHeaderField])) {
        $responseHeaders[$responseHeaderField] = $this->headerize($requestHeaders[$requestHeaderField]);
    } else {
        $requestedData = preg_split('/[\\s,]+/', $requestHeaders[$requestHeaderField], -1, PREG_SPLIT_NO_EMPTY);
        $acceptedData = array_uintersect($requestedData, $this->cors[$requestHeaderField], 'strcasecmp');
        if (!empty($acceptedData)) {
            $responseHeaders[$responseHeaderField] = implode(', ', $acceptedData);
        }
    }
}

            
prepareHeaders() public 方法

為每個 CORS 標頭建立特定的回應。

public array prepareHeaders ( $requestHeaders )
$requestHeaders 陣列

我們偵測到的 CORS 標頭

return 陣列

準備好要傳送的 CORS 標頭

                public function prepareHeaders($requestHeaders)
{
    $responseHeaders = [];
    // handle Origin
    if (isset($requestHeaders['Origin'], $this->cors['Origin'])) {
        if (in_array($requestHeaders['Origin'], $this->cors['Origin'], true)) {
            $responseHeaders['Access-Control-Allow-Origin'] = $requestHeaders['Origin'];
        }
        if (in_array('*', $this->cors['Origin'], true)) {
            // Per CORS standard (https://fetch.spec.whatwg.org), wildcard origins shouldn't be used together with credentials
            if (isset($this->cors['Access-Control-Allow-Credentials']) && $this->cors['Access-Control-Allow-Credentials']) {
                if (YII_DEBUG) {
                    throw new InvalidConfigException("Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration.");
                } else {
                    Yii::error("Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration.", __METHOD__);
                }
            } else {
                $responseHeaders['Access-Control-Allow-Origin'] = '*';
            }
        }
    }
    $this->prepareAllowHeaders('Headers', $requestHeaders, $responseHeaders);
    if (isset($requestHeaders['Access-Control-Request-Method'])) {
        $responseHeaders['Access-Control-Allow-Methods'] = implode(', ', $this->cors['Access-Control-Request-Method']);
    }
    if (isset($this->cors['Access-Control-Allow-Credentials'])) {
        $responseHeaders['Access-Control-Allow-Credentials'] = $this->cors['Access-Control-Allow-Credentials'] ? 'true' : 'false';
    }
    if (isset($this->cors['Access-Control-Max-Age']) && $this->request->getIsOptions()) {
        $responseHeaders['Access-Control-Max-Age'] = $this->cors['Access-Control-Max-Age'];
    }
    if (isset($this->cors['Access-Control-Expose-Headers'])) {
        $responseHeaders['Access-Control-Expose-Headers'] = implode(', ', $this->cors['Access-Control-Expose-Headers']);
    }
    if (isset($this->cors['Access-Control-Allow-Headers'])) {
        $responseHeaders['Access-Control-Allow-Headers'] = implode(', ', $this->cors['Access-Control-Allow-Headers']);
    }
    return $responseHeaders;
}