LoginSignup
50
46

More than 5 years have passed since last update.

Node.js製のプロキシHoxyを使い、任意のURLでlocalhostにアクセスする

Last updated at Posted at 2015-08-19

フロントエンド開発をする際、Browsersyncなどを使ってlocalhostサーバを立てることは多いかと思います。この記事は、サーバ側のAPIやCookieの都合から、本番環境のURLでそのローカルサーバにアクセスしたくなったとき向けのTipsです。

やり方はいくつもありそうですが、ここではHoxyというNode.js上で動作するプロキシサーバを、gulpと連携させて使う方法を紹介します。
Node製のプロキシを選んだのは、外部ツールのインストールや、hostsの書き換えをせずにサクッと環境構築できるようにするためです。

実現すること

  • ブラウザでhttp://example.com/(任意のURL)にアクセスすると、ローカルのコンテンツが表示される
  • 開発中はlivereloadなどBrowsersyncの各種機能が利用できる
  • npm install && gulpだけで環境を共有できる(重要!)

Hoxyとは

公式サイト : http://greim.github.io/hoxy/

FiddlerCharlesのようなデバッグ用プロキシの一種です。
ただしGUIを持たず、Node.jsのAPIを使ってプロキシの設定や起動を行います。

今回はリクエスト先のドメインを置き換えるという簡単な使い方しかしませんが、レイテンシを再現したり、レスポンスbodyを改変するといった高度な使い方もサポートしています。

プロキシサーバの設定

プロキシサーバはHoxyを使い、localhost:8888に立てることにします。

Hoxyの.intercept()メソッドを使い、example.comへのリクエストがlocalhost:9000に向かうように置き換えます。もちろん下層ページや、Browsersyncが使うWebSocketの通信もこれで置き換えられます。

var hoxy = require('hoxy');
var proxy = hoxy.createServer().listen(8888);
proxy.intercept({
  phase: 'request',
  hostname: 'example.com'
}, function (req) {
  req.hostname = 'localhost';
  req.port = '9000';
});

この例ではホスト名がexample.comのすべてのリクエストを対象としていますが、.intercept()のオプションを変更することで、正規表現によるURLの絞り込みや、特定のMIMEタイプだけを対象にすることもできます。

対象以外のリクエストは、通常どおりインターネット上のコンテンツを参照します。本番環境からのレスポンスとローカルのファイルを混ぜてページを構成することが可能です。

Webサーバの設定

appディレクトリをルートとしたBrowsersyncサーバを、localhost:9000に作ります。

そのままhttp://localhost:9000/としてアクセスすることもできますが、さきほどのプロキシを通せば、同じコンテンツがhttp://example.com/でも閲覧できるようになります。

var browserSync = require('browser-sync').create();
browserSync.init({
  notify: false,
  port: 9000,
  open: false,
  server: {
    baseDir: 'app'
  }
});

gulpタスクとして実装

gulpを使い、上記のサーバをコマンド1つで起動できるようにします。

gulpfile.js

'use strict';

var gulp = require('gulp');
var $ = require('gulp-load-plugins');
var browserSync = require('browser-sync').create();
var hoxy = require('hoxy');
var opn = require('opn');

var hostname = 'example.com';

gulp.task('proxy', function (callback) {
  var proxy = hoxy.createServer().listen(8888, function () {
    callback();
  });
  proxy.intercept({
    phase: 'request',
    hostname: hostname
  }, function (req) {
    req.hostname = 'localhost';
    req.port = '9000';
  });
});

gulp.task('serve', ['proxy'], function () {
  browserSync.init({
    notify: false,
    port: 9000,
    open: false,
    server: {
      baseDir: 'app'
    }
  }, function () {
    opn('http://' + hostname);
  });
  gulp.watch([
    'app/**'
  ]).on('change', browserSync.reload);
});

gulp.task('default', ['serve']);

gulp(またはgulp serve)コマンドで2つのサーバを順に起動し、さらにhttp://example.com/を自動的にブラウザで開くよう設定しています。
また、コンテンツ(appディレクトリ配下のファイル)を更新すると、自動的にページがリロードされます。

動作確認

プロキシを使わずにhttp://example.com/へアクセス(→本番環境)
本番環境

localhost:8888プロキシを設定してhttp://example.com/にアクセス(→ローカル環境)
ローカル環境

デモプロジェクト

package.jsonを含んだ全ソースコードは、GitHubにて公開しています。

おまけ: localhostを立てずに直接ファイルを差し替える

この記事では、Browsersyncのサーバを使いたかったため、example.comに対しlocalhost:9000を参照させるという方法を取りました。
しかし単純に特定のリクエストをローカルファイルに差し替えるだけなら、Hoxyのcycleインスタンスを使って実現できます。

proxy.intercept({
  phase: 'request',
  fullUrl: 'http://example.com/main.js'
}, function (req, resp, cycle) {
  return cycle.serve(__dirname + '/main.js');
});

この方法については、Hoxy - Class Cycleのドキュメントに詳しく載っています。

50
46
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
46