title: Cross-Origin Request (CORS) in ( Yii2 Framework + Ionic )
body: <p>I'm trying to make some HTTP requests from my Ionic project to my Yii2 backend. But when I try to get data I'm getting the cross-origin issue, I don't know what to change in my Yii2 settings.</p>
  <p>I've already tried to make a proxy for my request, and also make Cordova request but none of them worked, I think it's all about Yii2 settings.</p>
  <p>Here is my filters/cors.php file in Yii2</p>
  <pre><code>class Cors extends ActionFilter
  {
      /**
       * @var Request the current request. If not set, the `request` application component will be used.
       */
      public $request;
      /**
       * @var Response the response to be sent. If not set, the `response` application component will be used.
       */
      public $response;
      /**
       * @var array define specific CORS rules for specific actions
       */
      public $actions = [];
      /**
       * @var array Basic headers handled for the CORS requests.
       */
      public $cors = [
          'Origin' =&gt; ['*'],
          'Access-Control-Request-Method' =&gt; ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
          'Access-Control-Request-Headers' =&gt; ['*'],
          'Access-Control-Allow-Credentials' =&gt; true,
          'Access-Control-Max-Age' =&gt; 86400
      ];
  
  
      /**
       * {@inheritdoc}
       */
      public function beforeAction($action)
      {
          $this-&gt;request = $this-&gt;request ?: Yii::$app-&gt;getRequest();
          $this-&gt;response = $this-&gt;response ?: Yii::$app-&gt;getResponse();
  
          $this-&gt;overrideDefaultSettings($action);
  
          $requestCorsHeaders = $this-&gt;extractHeaders();
          $responseCorsHeaders = $this-&gt;prepareHeaders($requestCorsHeaders);
          $this-&gt;addCorsHeaders($this-&gt;response, $responseCorsHeaders);
  
          if ($this-&gt;request-&gt;isOptions &amp;&amp; $this-&gt;request-&gt;headers-&gt;has('Access-Control-Request-Method')) {
              // it is CORS preflight request, respond with 200 OK without further processing
              $this-&gt;response-&gt;setStatusCode(200);
              return false;
          }
  
          return true;
      }
  
      /**
       * Override settings for specific action.
       * @param \yii\base\Action $action the action settings to override
       */
      public function overrideDefaultSettings($action)
      {
          if (isset($this-&gt;actions[$action-&gt;id])) {
              $actionParams = $this-&gt;actions[$action-&gt;id];
              $actionParamsKeys = array_keys($actionParams);
              foreach ($this-&gt;cors as $headerField =&gt; $headerValue) {
                  if (in_array($headerField, $actionParamsKeys)) {
                      $this-&gt;cors[$headerField] = $actionParams[$headerField];
                  }
              }
          }
      }
  
      /**
       * Extract CORS headers from the request.
       * @return array CORS headers to handle
       */
      public function extractHeaders()
      {
          $headers = [];
          foreach (array_keys($this-&gt;cors) as $headerField) {
              $serverField = $this-&gt;headerizeToPhp($headerField);
              $headerData = isset($_SERVER[$serverField]) ? $_SERVER[$serverField] : null;
              if ($headerData !== null) {
                  $headers[$headerField] = $headerData;
              }
          }
  
          return $headers;
      }
  
      /**
       * For each CORS headers create the specific response.
       * @param array $requestHeaders CORS headers we have detected
       * @return array CORS headers ready to be sent
       */
      public function prepareHeaders($requestHeaders)
      {
          $responseHeaders = [];
          // handle Origin
          if (isset($requestHeaders['Origin'], $this-&gt;cors['Origin'])) {
              if (in_array($requestHeaders['Origin'], $this-&gt;cors['Origin'], true)) {
                  $responseHeaders['Access-Control-Allow-Origin'] = $requestHeaders['Origin'];
              }
  
              if (in_array('*', $this-&gt;cors['Origin'], true)) {
                  // Per CORS standard (https://fetch.spec.whatwg.org), wildcard origins shouldn't be used together with credentials
                  if (isset($this-&gt;cors['Access-Control-Allow-Credentials']) &amp;&amp; $this-&gt;cors['Access-Control-Allow-Credentials']) {
                      if (YII_DEBUG) {
                          throw new InvalidConfigException(&quot;Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration.&quot;);
                      } else {
                          Yii::error(&quot;Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration.&quot;, __METHOD__);
                      }
                  } else {
                      $responseHeaders['Access-Control-Allow-Origin'] = '*';
                  }
              }
          }
  
          $this-&gt;prepareAllowHeaders('Headers', $requestHeaders, $responseHeaders);
  
          if (isset($requestHeaders['Access-Control-Request-Method'])) {
              $responseHeaders['Access-Control-Allow-Methods'] = implode(', ', $this-&gt;cors['Access-Control-Request-Method']);
          }
  
          if (isset($this-&gt;cors['Access-Control-Allow-Credentials'])) {
              $responseHeaders['Access-Control-Allow-Credentials'] = $this-&gt;cors['Access-Control-Allow-Credentials'] ? 'true' : 'false';
          }
  
          if (isset($this-&gt;cors['Access-Control-Max-Age']) &amp;&amp; $this-&gt;request-&gt;getIsOptions()) {
              $responseHeaders['Access-Control-Max-Age'] = $this-&gt;cors['Access-Control-Max-Age'];
          }   
  
          if (isset($this-&gt;cors['Access-Control-Expose-Headers'])) {
              $responseHeaders['Access-Control-Expose-Headers'] = implode(', ', $this-&gt;cors['Access-Control-Expose-Headers']);
          }
          
          if (isset($this-&gt;cors['Access-Control-Allow-Headers'])) {
              $responseHeaders['Access-Control-Allow-Headers'] = implode(', ', $this-&gt;cors['Access-Control-Allow-Headers']);
          }
  
          return $responseHeaders;
      }
  
      /**
       * Handle classic CORS request to avoid duplicate code.
       * @param string $type the kind of headers we would handle
       * @param array $requestHeaders CORS headers request by client
       * @param array $responseHeaders CORS response headers sent to the client
       */
      protected function prepareAllowHeaders($type, $requestHeaders, &amp;$responseHeaders)
      {
          $requestHeaderField = 'Access-Control-Request-' . $type;
          $responseHeaderField = 'Access-Control-Allow-' . $type;
          if (!isset($requestHeaders[$requestHeaderField], $this-&gt;cors[$requestHeaderField])) {
              return;
          }
          if (in_array('*', $this-&gt;cors[$requestHeaderField])) {
              $responseHeaders[$responseHeaderField] = $this-&gt;headerize($requestHeaders[$requestHeaderField]);
          } else {
              $requestedData = preg_split('/[\\s,]+/', $requestHeaders[$requestHeaderField], -1, PREG_SPLIT_NO_EMPTY);
              $acceptedData = array_uintersect($requestedData, $this-&gt;cors[$requestHeaderField], 'strcasecmp');
              if (!empty($acceptedData)) {
                  $responseHeaders[$responseHeaderField] = implode(', ', $acceptedData);
              }
          }
      }
  
      /**
       * Adds the CORS headers to the response.
       * @param Response $response
       * @param array $headers CORS headers which have been computed
       */
      public function addCorsHeaders($response, $headers)
      {
          if (empty($headers) === false) {
              $responseHeaders = $response-&gt;getHeaders();
              foreach ($headers as $field =&gt; $value) {
                  $responseHeaders-&gt;set($field, $value);
              }
          }
      }
  
      /**
       * Convert any string (including php headers with HTTP prefix) to header format.
       *
       * Example:
       *  - X-PINGOTHER -&gt; X-Pingother
       *  - X_PINGOTHER -&gt; X-Pingother
       * @param string $string string to convert
       * @return string the result in &quot;header&quot; format
       */
      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);
      }
  
      /**
       * Convert any string (including php headers with HTTP prefix) to header format.
       *
       * Example:
       *  - X-Pingother -&gt; HTTP_X_PINGOTHER
       *  - X PINGOTHER -&gt; HTTP_X_PINGOTHER
       * @param string $string string to convert
       * @return string the result in &quot;php $_SERVER header&quot; format
       */
      protected function headerizeToPhp($string)
      {
          return 'HTTP_' . strtoupper(str_replace([' ', '-'], ['_', '_'], $string));
      }
  }
  
  </code></pre>
  <p>I expect to get the same JSON data in my Ionic app that I get when I enter the URL in the browser.</p>