title: CORS issue while shaping working web app into a native Ionic app for Android
body: <p>I've been trying to set up this <strong>Ionic CLI proxy server</strong> following this <a href="https://ionicframework.com/blog/handling-cors-issues-in-ionic/" rel="nofollow noreferrer">guide</a>, but it's from 2015 and I have no idea how to implement it in Angular 10.</p>
  <p>So when I run my app with a command:</p>
  <pre><code>ionic capacitor run android --project=myApp -c=production
  </code></pre>
  <p>I have this error in Android Studio:</p>
  <pre><code>E/Capacitor/Console: File: http://localhost/login - Line 0 - Msg: Access to XMLHttpRequest at 'https://remoteServer.com/api/v1/oauth/v2/token' from origin 'http://localhost' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' head
  </code></pre>
  <p>This is my <strong>capacitor.config.json</strong> file:</p>
  <pre><code>{
    &quot;appId&quot;: &quot;io.ionic.starter&quot;,
    &quot;appName&quot;: &quot;myApp&quot;,
    &quot;bundledWebRuntime&quot;: false,
    &quot;npmClient&quot;: &quot;npm&quot;,
    &quot;webDir&quot;: &quot;www&quot;,
    &quot;plugins&quot;: {
      &quot;SplashScreen&quot;: {
        &quot;launchShowDuration&quot;: 0
      }
    },
    &quot;cordova&quot;: {},
    &quot;linuxAndroidStudioPath&quot;: &quot;/opt/android-studio/bin/studio.sh&quot;
  }
  </code></pre>
  <p>And this is my <strong>ionic.config.json</strong> file:</p>
  <pre><code>{
    &quot;name&quot;: &quot;myApp&quot;,
    &quot;integrations&quot;: {
      &quot;capacitor&quot;: {}
    },
    &quot;type&quot;: &quot;angular&quot;,
    &quot;proxies&quot;: [
      {
        &quot;path&quot;: &quot;/api&quot;,
        &quot;proxyUrl&quot;: &quot;https://remoteServer.com/api&quot;
      }
    ]
  }
  </code></pre>
  <p>ionic info</p>
  <pre><code>Ionic:
  
     Ionic CLI                     : 6.10.1 (/home/user/.nvm/versions/node/v12.18.3/lib/node_modules/@ionic/cli)
     Ionic Framework               : @ionic/angular 5.3.1
     @angular-devkit/build-angular : 0.1000.5
     @angular-devkit/schematics    : 10.0.5
     @angular/cli                  : 10.0.5
     @ionic/angular-toolkit        : 2.3.3
  
  Capacitor:
  
     Capacitor CLI   : 2.4.0
     @capacitor/core : 2.4.0
  
  Utility:
  
     cordova-res : not installed
     native-run  : not installed
  
  System:
  
     NodeJS : v12.18.3 (/home/user/.nvm/versions/node/v12.18.3/bin/node)
     npm    : 6.14.6
     OS     : Linux 5.4
  </code></pre>
  <p>Any ideas how to resolve this? I've been searching for ages...</p>
  <hr />
  <p>edit:</p>
  <p>So I followed Angular's instructions on <a href="https://angular.io/guide/http#intercepting-requests-and-responses" rel="nofollow noreferrer">how to make an interceptor</a> and this article that explains <a href="https://manuel-heidrich.dev/blog/an-elegant-way-to-handle-native-http-requests-with-cordova-advanced-http-in-an-ionic-app/" rel="nofollow noreferrer">how to implement both HttpClient and Ionic's native HTTP</a>, but I run into new issues.</p>
  <p>Using the code from article, TS is complaining about this line:</p>
  <p><code>headers: nativeHttpResponse.headers</code></p>
  <pre><code>(property) headers?: HttpHeaders
  Type '{ [key: string]: string; }' is missing the following properties from type 'HttpHeaders': headers, normalizedNames, lazyInit, lazyUpdate, and 12 more.ts(2740)
  http.d.ts(3406, 9): The expected type comes from property 'headers' which is declared here on type '{ body?: any; headers?: HttpHeaders; status?: number; statusText?: string; url?: string; }'
  </code></pre>
  <p>Here's the whole native-http.interceptor.ts:</p>
  <pre><code>import { Injectable } from &quot;@angular/core&quot;;
  import {
    HttpInterceptor,
    HttpRequest,
    HttpHandler,
    HttpEvent,
    HttpResponse,
  } from &quot;@angular/common/http&quot;;
  import { Observable, from } from &quot;rxjs&quot;;
  import { Platform } from &quot;@ionic/angular&quot;;
  import { HTTP } from &quot;@ionic-native/http/ngx&quot;;
  
  type HttpMethod =
    | &quot;get&quot;
    | &quot;post&quot;
    | &quot;put&quot;
    | &quot;patch&quot;
    | &quot;head&quot;
    | &quot;delete&quot;
    | &quot;upload&quot;
    | &quot;download&quot;;
  
  @Injectable()
  export class NativeHttpInterceptor implements HttpInterceptor {
    constructor(private nativeHttp: HTTP, private platform: Platform) {}
  
    public intercept(
      request: HttpRequest&lt;any&gt;,
      next: HttpHandler
    ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
      if (!this.platform.is(&quot;cordova&quot;)) {
        return next.handle(request);
      }
  
      return from(this.handleNativeRequest(request));
    }
  
    private async handleNativeRequest(
      request: HttpRequest&lt;any&gt;
    ): Promise&lt;HttpResponse&lt;any&gt;&gt; {
      const headerKeys = request.headers.keys();
      const headers = {};
  
      headerKeys.forEach((key) =&gt; {
        headers[key] = request.headers.get(key);
      });
  
      try {
        await this.platform.ready();
  
        const method = &lt;HttpMethod&gt;request.method.toLowerCase();
  
        // console.log(‘— Request url’);
        // console.log(request.url)
        // console.log(‘— Request body’);
        // console.log(request.body);
  
        const nativeHttpResponse = await this.nativeHttp.sendRequest(
          request.url,
          {
            method: method,
            data: request.body,
            headers: headers,
            serializer: &quot;json&quot;,
          }
        );
  
        let body;
  
        try {
          body = JSON.parse(nativeHttpResponse.data);
        } catch (error) {
          body = { response: nativeHttpResponse.data };
        }
  
        const response = new HttpResponse({
          body: body,
          status: nativeHttpResponse.status,
          headers: nativeHttpResponse.headers,  &lt;--------
          url: nativeHttpResponse.url,
        });
  
        // console.log(‘— Response success’)
        // console.log(response);
  
        return Promise.resolve(response);
      } catch (error) {
        if (!error.status) {
          return Promise.reject(error);
        }
  
        const response = new HttpResponse({
          body: JSON.parse(error.error),
          status: error.status,
          headers: error.headers,
          url: error.url,
        });
  
        return Promise.reject(response);
      }
    }
  }
  </code></pre>
  <p>Here's how my <code>app.module.ts</code> looks like:</p>
  <pre><code>import { BrowserModule } from '@angular/platform-browser';
  import { NgModule } from '@angular/core';
  import { RouterModule } from '@angular/router';
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
  import { IonicModule } from '@ionic/angular';
  import { HTTP } from '@ionic-native/http/ngx';
  
  import { CoreModule } from './core/core.module';
  import { SharedModule } from './shared/shared.module';
  import { AppComponent } from './app.component';
  import { PageNotFoundComponent } from './shared/page-not-found/page-not-found.component';
  import { appRoutes } from './app.routes';
  
  
  @NgModule({
    imports: [
      BrowserModule,
      BrowserAnimationsModule,
      FormsModule,
      ReactiveFormsModule,
      SharedModule,
      CoreModule,
      RouterModule.forRoot(
        appRoutes
      ),
      IonicModule.forRoot()
    ],
    providers: [HTTP],
    declarations: [
      AppComponent,
      PageNotFoundComponent
    ],
    bootstrap: [AppComponent]
  })
  export class AppModule { }
  </code></pre>
  <p>Andd here is how my <code>core.module.ts</code> (where I want to use interceptor) looks like:</p>
  <pre><code>import { NgModule } from &quot;@angular/core&quot;;
  import { CommonModule } from &quot;@angular/common&quot;;
  import { HTTP_INTERCEPTORS, HttpClientModule } from &quot;@angular/common/http&quot;;
  
  import { NativeHttpInterceptor } from &quot;./service/native-http.interceptor&quot;;
  import { AuthService } from &quot;./service/auth.service&quot;;
  import { ApiService } from &quot;./service/api.service&quot;;
  import { AuthGuardService } from &quot;./service/auth-guard.service&quot;;
  import { AuthInterceptor } from &quot;./service/auth-interceptor&quot;;
  import { WindowRef } from &quot;./service/window-ref-service&quot;;
  
  @NgModule({
    imports: [CommonModule, HttpClientModule],
    providers: [
      {
        provide: HTTP_INTERCEPTORS,
        useClass: NativeHttpInterceptor,
        multi: true,
      },
      AuthService,
      ApiService,
      AuthGuardService,
      WindowRef,
      {
        provide: HTTP_INTERCEPTORS,
        useClass: AuthInterceptor,
        multi: true,
      },
    ],
  })
  export class CoreModule {}
  </code></pre>