かみのメモ

コンピュータビジョン・プログラムな話題中心の勉強メモ(記事一覧は https://kamino.hatenablog.com/archive へ)

AngularでHttpClientのgetのためにbase-hrefを取得する

どういう状況?

Angular 6.1.3でアプリを作っているときのこと。

「最終的にxxxx.example.comにデプロイするけど、とりあえずデモのためにxxxx.github.io/xxxx.example.comで公開したいな」と思いたちました。

そこでangular-cli-ghpagesを使って、

ng build --prod --base-href "https://xxxx.github.io/xxxx.example.com"
angular-cli-ghpages --repo=https://github.com/~~~~~~~

みたいな感じで公開しようとしました。

ところが、

//省略

export DataService {
  constructor(private http: HttpClient) { }

  getTopics() {
    return this.http.get('/data/topics.json');
  }
}

のように、静的なJSONファイルを取得しようとしたときhttps://xxxx.github.io/data/topics.jsonにアクセスしてしまい404が返ってきてしまいました。 実際にファイルが置かれているのはhttps://xxxx.github.io/xxxx.example.com/data/topics.jsonです。

どうやらHttpClientget()はホスト名を参照するのであって、base-hrefを参照してくれるわけではないようです。

解決方法

調べてみるとコードにbaseUrl: String = 'xxxx.github.io/xxxx.example.com';を埋め込む方法がよく紹介されていましたが、今回は最終的にxxxx.example.comにデプロイしたいので固定値を埋め込むのは遠慮したいところです。

かと言って、DOMを介して取得する、みたいな泥臭い方法は取りたくないです。

という感じで調べていくとこんな記述を見つけました。 どうやらLocationprepareExternalUrlが使えるようです。

ということでコードを修正。

import { Location } from '@angular/common';

//省略

export DataService {
  constructor(private http: HttpClient, private location: Location) { }

  getTopics() {
    return this.http.get(this.location.prepareExternalUrl('/data/topics.json'));
  }
}

これで動きました!