質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

proxy

proxy(プロキシー)は、企業などの内部コンピュータとインターネットの中間に位置し、例えば直接インターネットに接続できない内部コンピュータの代理としてインターネットに接続する等をするシステム、もしくは代理として機能を実行するソフトウェアです。内部ネットワークへのアクセスを一元管理し、内部からの特定の種類の接続以外を遮断すること、外部からの不正アクセスを拒否することなどに用いられます。

Q&A

解決済

1回答

4593閲覧

Node.js (Express) で動くアプリケーションをサブディレクトリ以下で動作させたい。

KitazawaShota

総合スコア7

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

proxy

proxy(プロキシー)は、企業などの内部コンピュータとインターネットの中間に位置し、例えば直接インターネットに接続できない内部コンピュータの代理としてインターネットに接続する等をするシステム、もしくは代理として機能を実行するソフトウェアです。内部ネットワークへのアクセスを一元管理し、内部からの特定の種類の接続以外を遮断すること、外部からの不正アクセスを拒否することなどに用いられます。

0グッド

0クリップ

投稿2017/09/15 15:48

###前提・実現したいこと
実現したいことは、表題の通り、Node.js (Express) で動くアプリケーションをサブディレクトリ以下で動作させることです。

現在CrowiというOSSのWikiアプリケーションのインストール作業を行っています。

最終目標はApacheによるプロキシ http://$ADDRESS/crowi/ を通じて Crowi にアクセスすることです。

そのため、Apacheのルートと合わせるためにCrowiを http://$ADDRESS:3000/crowi/ 以下で動かしたいです。

なお、Crowiは http://$ADDRESS:3000/ 以下で動く設計となっており、cssやjs等の静的ファイルや、redirectパスは絶対パスで書かれています。
そのため、http://$ADDRESS/crowi/http://$ADDRESS:3000/ にマッピングすると css, js が読み込まれなかったり、リンク先が http://$ADDRESS/hoge (つまりリンク先は /crowi/ 以下ではない) となってしまいます。

Node.js (Express) に、サブディレクトリ以下でWebアプリケーションを動作させる機能 はあるのでしょうか。
できれば、Crowiのソースコードのルートを一つ一つ編集することは避けたいと思っています。

なお、Railsの場合、以下の方法でできるそうです。(以下が私のやりたいことです)

よろしくお願いいたします。

###該当のソースコード

###補足情報(言語/FW/ツール等のバージョンなど)

node v6.11.3
Crowi 1.6.2

http://$ADDRESS:3000/ でのCrowiの動作は確認済みです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

プログラムで、サブディレクトリにアプリケーションを配置することを検証してみました。

Railsのような機能を使えるか

なお、Railsの場合、以下の方法でできるそうです。(以下が私のやりたいことです)

Expressにはそのような機能はありません(多分)
あったとしても、今回はその方法は使えないと思います。
使えない理由は、
crowiは、HTMLに直接パスを書いてあり、サブディレクトリを変更しても、ページが変更されないからです。(以下参照)

html

1<ul class="nav nav-tabs"> 2 <li><a href="/me"><i class="fa fa-gears"></i> {{ t('User Information') }}</a></li> 3 <li><a href="/me/password"><i class="fa fa-key"></i> {{ t('Password Setting') }}</a></li> 4 <li class="active"><a href="/me/apiToken"><i class="fa fa-rocket"></i> {{ t('API Settings') }}</a></li> 5</ul>

サブディレクトリにアプリケーションを配置してみる

よって、サブディレクトリにアプリケーションを配置するには、気合of気合ですべてのパスを変更するしかないと考えます。
プログラムを読んでいくと、crowi/lib/routes/index.jsに次のような記述があります。
ここのプログラムは、ルーティングの設定を行っています。

javascript

1app.get('/' , loginRequired(crowi, app) , page.pageListShow); 2 3app.get('/installer' , middleware.applicationNotInstalled() , installer.index); 4app.post('/installer/createAdmin' , middleware.applicationNotInstalled() , form.register , csrf, installer.createAdmin); 5//app.post('/installer/user' , middleware.applicationNotInstalled() , installer.createFirstUser); 6 7app.get('/login/error/:reason' , login.error); 8 9//以下省略

これを気合で次のように変更します。

shell

1sed -i -e "s/app\.post('\//app\.post('\/crowi\//g" -e "s/app\.get('\//app\.get('\/crowi\//g" lib/routes/index.js

javascript

1app.get('/crowi/' , loginRequired(crowi, app) , page.pageListShow); 2 3app.get('/crowi/installer' , middleware.applicationNotInstalled() , installer.index); 4app.post('/crowi/installer/createAdmin' , middleware.applicationNotInstalled() , form.register , csrf, installer.createAdmin); 5//app.post('/crowi/installer/user' , middleware.applicationNotInstalled() , installer.createFirstUser); 6 7app.get('/crowi/login/error/:reason' , login.error); 8 9//以下省略

これで、cssやhtmlの配置がきれいに見えるようになるのですが、リダイレクトを用いたページ遷移がうまいこと動きません。(非ログイン状態ならログインページにリダイレクト等)
リダイレクトを行っている部分は、次の部分(一部抜粋)です。

javascript

1// ログイン済みならさようなら 2if (req.user) { 3 return res.redirect('/'); 4} 5 6// config で closed ならさよなら 7if (config.crowi['security:registrationMode'] == Config.SECURITY_REGISTRATION_MODE_CLOSED) { 8 return res.redirect('/'); 9}

これも、気合で変更します。

shell

1sed -i -e "s/return res\.redirect('\//return res\.redirect('\/crowi\//g" lib/routes/logout.js 2sed -i -e "s/return res\.redirect('\//return res\.redirect('\/crowi\//g" lib/routes/login.js 3sed -i -e "s/return res\.redirect('\//return res\.redirect('\/crowi\//g" lib/routes/me.js 4sed -i -e "s/return res\.redirect('\//return res\.redirect('\/crowi\//g" lib/routes/admin.js 5sed -i -e "s/return res\.redirect('\//return res\.redirect('\/crowi\//g" lib/util/middlewares.js 6sed -i -e "s/return res\.redirect('\//return res\.redirect('\/crowi\//g" lib/routes/installer.js

javascript

1// ログイン済みならさようなら 2if (req.user) { 3 return res.redirect('/crowi/'); 4} 5 6// config で closed ならさよなら 7if (config.crowi['security:registrationMode'] == Config.SECURITY_REGISTRATION_MODE_CLOSED) { 8 return res.redirect('/crowi/'); 9}

これで、いい感じにリダイレクトできるのですが、FormのPOST先のパスを変えないといけません。
POST先を指定しているのは、以下の部分です(一部抜粋)

html

1<form role="form" action="/admin/user/invite" method="post"> 2 <div id="inviteUserForm" class="collapse"> 3 {% if sUser.status == 1 %} 4 <form action="/admin/user/{{ sUser._id.toString() }}/activate" method="post">

これを気合で変更します。

shell

1sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/admin/users.html 2sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/me/index.html 3sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/admin/search.html 4sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/login.html 5sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/admin/app.html 6sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/me/api_token.html 7sed -i -e "s/action=\"\//action=\"\/crowi\//g" resource/js/components/HeaderSearchBox/SearchForm.js 8sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/_form.html 9sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/installer.html 10sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/invited.html 11sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/me/password.html 12sed -i -e "s/action=\"\//action=\"\/crowi\//g" lib/views/admin/notification.html

html

1<form role="form" action="/crowi/admin/user/invite" method="post"> 2 <div id="inviteUserForm" class="collapse"> 3 {% if sUser.status == 1 %} 4 <form action="/crowi/admin/user/{{ sUser._id.toString() }}/activate" method="post">

と、言う感じで aタグのherf, scriptタグのsrc等を気合で変更すれば、動くと思います。

まとめ

気合of気合

投稿2017/09/15 23:25

no_______nonono

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KitazawaShota

2017/09/16 01:13

回答ありがとうございます。 静的ファイルに絶対パスが書かれていた場合 Node.js 側ではなにもやりようがないということを失念していました。たしかにその場合、Expressにサブディレクトリで動かす機能があっても静的ファイルのリンク先が死にますね・・・。 わざわざ検証ありがとうございます。気合of気合and気合で頑張ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問