HttpClientModule触发两个请求,其中一个请求没有身份验证标头。我究竟做错了什么?

时间:2018-06-15 19:02:22

标签: angular ionic-framework angular-httpclient

我正在使用Ionic 3上角度为4.3的HttpClientModule。我的应用程序与Django服务器通信,该服务器要求拦截器发送一个身份验证头。我面临的问题是,当我要求HttpClientModule执行get请求时,它会发送两个请求。一个具有认证头,没有响应,另一个没有认证头。谁能帮我?我不知道我做错了什么:(

以下是我在Web Inspector中看到的内容:

RFC3164

First request sent

这是我的提供者:

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { LoadingController, AlertController } from 'ionic-angular';

@Injectable()
export class RestProvider {

    private url = "http://10.0.1.50:8000/";

    constructor(public http: HttpClient, private alertCtrl: AlertController, private loadingCtrl: LoadingController) { }

    getDisp(){
        return new Promise(resolve => {
            this.http.get(this.url+'api/Dispositivos').subscribe(data => {
                console.log(data);
                resolve(data);
            }, (err: HttpErrorResponse) => {
                if (err instanceof ErrorEvent){
                    let alert = this.alertCtrl.create({
                        title: 'Algo deu errado :(',
                        subTitle: 'Parece que há algo errado com a sua conexão. Tente novamente',
                        buttons: ['OK']
                    });
                    alert.present();
                } else {
                    let alert = this.alertCtrl.create({
                        title: 'Algo deu errado :(',
                        subTitle: 'Desculpe, parece que nossos servidores estão com problemas. Tente novamente em alguns minutos',
                        buttons: ['OK']
                    });
                    alert.present();
                }
            });
        });
    }

}

这是我的拦截器:

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';



@Injectable()
export class TokenInterceptor implements HttpInterceptor {

    public credenciais: any;

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        if (localStorage.credenciais != null) {
            this.credenciais = JSON.parse(localStorage.credenciais)
            request = request.clone({
                setHeaders: {
                    Authorization: 'Token '+this.credenciais.token
                }
            });
        }
        return next.handle(request);
    }
}

这是我用来调用提供者的函数:

import { NavController } from 'ionic-angular';
import { LoginPage } from "../../pages/login/login";
import { RestProvider } from '../../providers/rest/rest';

[...]

constructor(public navCtrl: NavController, public restProvider: RestProvider) {}

[...]

carregaDisp(){
    return new Promise(resolve => {
        this.restProvider.getDisp().then(data => {
            if (data == null) {
                this.navCtrl.setRoot(LoginPage);
            } else {
                this.dispositivo = data;
                this.atualizaStatus().then(() => {
                    console.log(data);
                    resolve();
                });
            }
        });
    });
}

我不知道我做错了什么,我用Google搜索了我能想到的一切。对不起,如果这是初学者的错误,但我找不到它的解决方案:(

1 个答案:

答案 0 :(得分:0)

我发现您的RestProvider存在问题。 您不应该订阅这样的observable。您只想在实际获得响应时订阅observable,我的意思是在使用地点,而不是在包装器方法中。它会导致内存泄漏。 您也应该取消订阅观察点,并且您的方式不允许您这样做。

请使用类似的东西。这样您将获得新的可管理运算符的优势并获得干净的声明性代码。

import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';

getDisp(): Promise<any> {
    return this.http
      .get(this.url + 'api/Dispositivos')
      .pipe(
        catchError(err => {
          this.processError(err);
          return of(err);
        }),
      )
      .toPromise();
  }

  processError(err) {
    if (err instanceof ErrorEvent) {
      let alert = this.alertCtrl.create({
        title: 'Algo deu errado :(',
        subTitle:
          'Parece que há algo errado com a sua conexão. Tente novamente',
        buttons: ['OK'],
      });
      alert.present();
    } else {
      let alert = this.alertCtrl.create({
        title: 'Algo deu errado :(',
        subTitle:
          'Desculpe, parece que nossos servidores estão com problemas. Tente novamente em alguns minutos',
        buttons: ['OK'],
      });
      alert.present();
    }
  }

此方法的用例示例如下:

 async refresh() {
    const response = await this.getDisp();
    console.log('response of the getdisp is : ', response);
  }