【问题标题】:Aurelia - Setting headers in Aurelia Fetch ClientAurelia - 在 Aurelia Fetch Client 中设置标题
【发布时间】:2017-12-17 04:33:23
【问题描述】:

我正在使用aurelia-http-client 并努力为我的请求使用拦截器和设置标头。

我需要实现的是;

  • 每个拦截器(请求、请求错误、响应和响应错误)在触发时使用aurelia-event-aggregator 发出一个事件。
  • 每个请求都会添加一个标头,其中包含在页面上输入的信息

让拦截器正确发布事件的唯一方法是在 main.js 中使用aurelia.container,如下所示;

import {HttpClient} from 'aurelia-http-client';
import {EventAggregator} from 'aurelia-event-aggregator';

export function configure(aurelia) {
  const container = aurelia.container;

  const httpClient = container.get(HttpClient);
  const ea = container.get(EventAggregator);

  httpClient.configure(config => {
    config.withInterceptor({
      request(request) {
        ea.publish('http-request', request);
        return request;
      },
      requestError(error) {
        ea.publish('http-request-error', error);
       throw error;
      },
      response(response) {
        ea.publish('http-response', response);
        return response;
      },
      responseError(error) {
        ea.publish('http-response-error', error);
        throw error;
      }
    });
  });

  aurelia.use
    .standardConfiguration()
    .developmentLogging()
    .singleton(HttpClient, httpClient);


  aurelia.start().then(() => aurelia.setRoot());
}

因为我的请求的标头必须在应用程序初始化后设置 - 我不能像大多数在线教程那样在上面的配置中执行此操作。

相反,它需要如下设置;

import {inject} from "aurelia-framework";
import {HttpClient} from "aurelia-http-client";
import {EventAggregator} from "aurelia-event-aggregator";

@inject(HttpClient, EventAggregator)
export class Dashboard {

  requestMethod = "GET";

  constructor(HttpClient, EventAggregator) {
    this.http = HttpClient;
    this.ea = EventAggregator;
  }

  triggerGet() {
    // HEADER NEEDS TO BE SET HERE USING THIS.FOO
    this.http.get(this.url).then(response => {
      console.log("GET Response", response);
    });
  }
}

我尝试过各种变体;

this.http.configure((configure) => {
  if(this.username && this.password) {
    configure.withDefaults({
      headers: {
        'Authorization': 'Basic ' + btoa(this.username + ":" + this.password)
      }
    });
  }
})

但我无法在需要的地方更改标题,并维护我在 main.js

中设置的配置

【问题讨论】:

  • 你不能把HttpClient 包装在你自己的类中,然后注入那个类吗?
  • configure.withDefault 只能用于设置静态标题。如果您的标头取决于变量,则应在拦截器中设置它。例如request(request) { request.headers.append('Authorization', appState.token); return request; }

标签: javascript aurelia-fetch-client aurelia


【解决方案1】:

cmets 中的 Fabio Luiz 让我找到了一个可行的解决方案。我认为这并不理想,但它确实有效。

我基本上创建了一个 AppState 类,用于将用户名/密码传递给拦截器;

export class AppState { 

  properties = {};

  clear() {
    this.properties = {};
  }

  set(key, value) {
    this.properties[key] = value;
  }

  get(key) {
    if(this.properties[key]) {
      return this.properties[key];
    } else {
      return false;
    }
  }
}

它相当粗糙且准备就绪,但它仅用于测试应用程序,所以我很满意。

这是它的用途;

import {inject} from "aurelia-framework";
import {HttpClient} from "aurelia-http-client";
import {EventAggregator} from "aurelia-event-aggregator";
import {AppState} from "services/appState";

@inject(HttpClient, EventAggregator, AppState)
export class Dashboard {

    constructor(HttpClient, EventAggregator, AppState) {
        this.http = HttpClient;
        this.ea = EventAggregator;
        this.appState = AppState;

        // Create listeners
    }

    run() {
        if(this.username && this.password) {
            this.appState.set('authenticate', true);
            this.appState.set('username', this.username);
            this.appState.set('password', this.password);
        }

        // Trigger HTTP Requests
    }
}

然后是我的 main.js 文件;

import {HttpClient} from 'aurelia-http-client';
import {EventAggregator} from 'aurelia-event-aggregator';
import {AppState} from 'services/appState';

export function configure(aurelia) {
    const container = aurelia.container;
    const httpClient = container.get(HttpClient);
    const ea = container.get(EventAggregator);
    const appState = container.get(AppState);

    httpClient.configure(config => {
        config.withInterceptor({
            request(request) {
                if(appState.get('authenticate')) {
                    let username = appState.get('username');
                    let password = appState.get('password');
                    request.headers.add("Authorization", "Basic " + btoa(username + ":" + password));
                }
                ea.publish('http-request', request);
                return request;
            },
            requestError(error) {
                ea.publish('http-request-error', error);
                throw error;
            },
            response(response) {
                ea.publish('http-response', response);
                return response;
            },
            responseError(error) {
                ea.publish('http-response-error', error);
                throw error;
            }
        });
    });

    aurelia.use
        .standardConfiguration()
        .developmentLogging()
        .singleton(HttpClient, httpClient);


      aurelia.start().then(() => aurelia.setRoot());
}

【讨论】:

    【解决方案2】:

    尝试像这样创建一个实际的标头对象:

    this.http.configure((configure) => {
      if(this.username && this.password) {
        configure.withDefaults({
            headers: new Headers({
              'Authorization': 'Basic ' + btoa(this.username + ":" + this.password)
            })
        });
      }
    })
    

    【讨论】:

      猜你喜欢
      • 2016-03-12
      • 2017-11-27
      • 1970-01-01
      • 2017-05-11
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 2018-03-11
      • 1970-01-01
      相关资源
      最近更新 更多