Angular 在实现ionic'时出现类型脚本错误;本机HTTP拦截器

Angular 在实现ionic'时出现类型脚本错误;本机HTTP拦截器,angular,typescript,ionic-framework,capacitor,ionic-native-http,Angular,Typescript,Ionic Framework,Capacitor,Ionic Native Http,当我遇到一些CORS问题时,我正在将Angular 10 web应用程序修改为ionic native应用程序。由于我无法在BE上更改任何内容,所以我遇到了Ionic的本机HTTP插件 我按照Angular的说明和这篇文章的解释,但我遇到了新的问题 TS使用文章中的代码抱怨这一行: headers:nativeHttpResponse.headers (property) headers?: HttpHeaders Type '{ [key: string]: string; }' is mis

当我遇到一些CORS问题时,我正在将Angular 10 web应用程序修改为ionic native应用程序。由于我无法在BE上更改任何内容,所以我遇到了Ionic的本机HTTP插件

我按照Angular的说明和这篇文章的解释,但我遇到了新的问题

TS使用文章中的代码抱怨这一行:

headers:nativeHttpResponse.headers

(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; }'
以下是整个本机http.interceptor.ts:

import { Injectable } from "@angular/core";
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpResponse,
} from "@angular/common/http";
import { Observable, from } from "rxjs";
import { Platform } from "@ionic/angular";
import { HTTP } from "@ionic-native/http/ngx";

type HttpMethod =
  | "get"
  | "post"
  | "put"
  | "patch"
  | "head"
  | "delete"
  | "upload"
  | "download";

@Injectable()
export class NativeHttpInterceptor implements HttpInterceptor {
  constructor(private nativeHttp: HTTP, private platform: Platform) {}

  public intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    if (!this.platform.is("cordova")) {
      return next.handle(request);
    }

    return from(this.handleNativeRequest(request));
  }

  private async handleNativeRequest(
    request: HttpRequest<any>
  ): Promise<HttpResponse<any>> {
    const headerKeys = request.headers.keys();
    const headers = {};

    headerKeys.forEach((key) => {
      headers[key] = request.headers.get(key);
    });

    try {
      await this.platform.ready();

      const method = <HttpMethod>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: "json",
        }
      );

      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,  <--------
        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);
    }
  }
}
Andd下面是我的
core.module.ts
(我想在这里使用拦截器)的样子:

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 { }
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http";

import { NativeHttpInterceptor } from "./service/native-http.interceptor";
import { AuthService } from "./service/auth.service";
import { ApiService } from "./service/api.service";
import { AuthGuardService } from "./service/auth-guard.service";
import { AuthInterceptor } from "./service/auth-interceptor";
import { WindowRef } from "./service/window-ref-service";

@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 {}
Angular的API设计笨拙。具体来说,它的构造函数需要Angular的实例,而不是接受Header的对象

因此,在您的情况下,正确的代码是

const response = new HttpResponse({
  body,
  status: nativeHttpResponse.status,
  headers: new HttpHeaders(nativeHttpResponse.headers),
  url: nativeHttpResponse.url
});
我认为这是糟糕的API设计——简单明了。它与常用的相应API(如
fetch
)不同,增加了耦合性,并且在迫使您编写样板文件的同时,它不是一种远程习惯用法。相比之下,爱奥尼亚本地团队采取了正确的方法,将头指定为对象。

Angular的API设计得很笨拙。具体来说,它的构造函数需要Angular的实例,而不是接受Header的对象

因此,在您的情况下,正确的代码是

const response = new HttpResponse({
  body,
  status: nativeHttpResponse.status,
  headers: new HttpHeaders(nativeHttpResponse.headers),
  url: nativeHttpResponse.url
});

我认为这是糟糕的API设计——简单明了。它与常用的相应API(如
fetch
)不同,增加了耦合性,并且在迫使您编写样板文件的同时,它不是一种远程习惯用法。相比之下,Ionic Native团队采用了正确的方法,将头指定为对象。

这只是一个设计糟糕的方法,因此需要编写
新的HttpResponse({headers:new HttpHeaders({…}),…})
。这类API的设计者应该受到谴责。@AluanHaddad啊,是的,
headers:new HttpHeaders(nativeHttpResponse.headers)
通过了TS检查。谢谢,这只是一个设计糟糕的程序,所以您需要编写
新的HttpResponse({headers:newhttpheaders({…}),…})
。这类API的设计者应该受到谴责。@AluanHaddad啊,是的,
headers:new HttpHeaders(nativeHttpResponse.headers)
通过了TS检查。非常感谢。