今年の初めに、node.jsを使用してExpressフレームワークに基づいてブログプログラムを書き直し、これからASP.NETに別れを告げることを計画しました。ただし、現在使用しているVPSはWindows Server SystemとIIS Serverです。 ExpressとIISの両方がポート80を聴くと、明らかな対立があります。幸いなことに、IISにnode.jsプログラムをホストするiisnodeという拡張機能があります。さらに、ホスティング後、IISのさまざまな機能を使用できることも意味します(プロセス管理、GZIP圧縮、ロギング、キャッシュ、許可制御、ドメイン名バインディングなど)。
iisnodeを使用するには、インストールする必要があります。
1.Node.js
2。IISURL書き換えモジュール
3.iisnode
インストール後、通常の操作に従ってIISマネージャーにサイトを作成し、Expressプログラムのディレクトリを指します。重要なのは、web.configファイルを追加することです。
コードコピーは次のとおりです。
<configuration>
<System.Webserver>
<ハンドラー>
<add name = "iisnode" path = "bin /www" verb = "*" modules = "iisnode" resourceType = "requidified" requirecass = "script" />
</handlers>
<書き直し>
<rules>
<ルールname = "all">
<match url = " /*" />
<action type = "rewrite" url = "bin /www" />
</rule>
</rules>
</書き換え>
</system.webserver>
</configuration>
このコンテンツは、IISマネージャーの視覚インターフェイスを介して構成することもできます。これは、すべてのリクエストをBin/wwwに書き換え、iisnode拡張機能を使用してBin/wwwを実行することを意味します。ただし、サイトを開いた後、エラーメッセージが表示されます。
コードコピーは次のとおりです。
リクエストフィルターモジュールは、Hiddensegmentセクションを含むURLのパスを拒否するように構成されています
最初は私はそれについて明確ではないと感じましたが、後にASP.NETのBinディレクトリがアクセスを許可されていない特別なディレクトリであることに突然気付きました。このルールにヒットするBin/wwwにリクエストを書き直します。したがって、たとえば、ディレクトリ名を変更するだけで、ビンを変更して起動します(良い練習ではないことが判明しました。後で話しましょう)。
コードコピーは次のとおりです。
<configuration>
<System.Webserver>
<ハンドラー>
<add name = "iisnode" path = "起動 /www" verb = "*" modules = "iisnode" resourceType = "requidified" requireccess = "script" />
</handlers>
<書き直し>
<rules>
<ルールname = "all">
<match url = " /*" />
<action type = "rewrite" url = "起動 /www" />
</rule>
</rules>
</書き換え>
</system.webserver>
</configuration>
IISマネージャーのサイトを再起動した後、再びアクセスして、最終的に実行を開始しました。簡単ではありませんでした!しかし、私はまだ幸せでした。
プログラム関数のテスト中に、取得したIPが空であることがわかりました。 Expressフレームワークでは、IPはReq.ipを介して取得され、リクエストヘッダーのremote_addrから値が取得されます。簡単なテストコードを通じて、remote_addrの値も空であることがわかりました。このヘッダー情報がIISからnode.jsまでのプロセス中に失われることは明らかです。 Googleの後、IISNodeにはこの問題があることがわかりました。公式の解決策は、X-Forword-forを使用することですが、別のソリューションを見つけました。
remote_addrを保持できるweb.config(</system.webserver>に追加する前に)に構成があります。
コードコピーは次のとおりです。
<iisnode prosomeservervars = "remote_addr" />
指示によると、予約されたremote_addrはx-iisnode-remote_addrに名前が変更されるため、req.ipの値を1回上書きし、Expressのapp.jsにミドルウェア関数を追加する必要があります。
コードコピーは次のとおりです。
app.use(function(req、res、next){
req.ip = req.headers ['x-iisnode-remote_addr'];
次();
});
ただし、この調整後、取得したIPはまだ空であるため、必然的にReq.ipの割り当てが失敗したかどうか疑問に思います。 Source of Expressコードを見ると、Req.ipが定義ゲッターを介して定義されていることがわかります。そのため、上書きするには、再度定義する必要があります。
コードコピーは次のとおりです。
app.use(function(req、res、next){
object.defineProperty(req、 'ip'、{
get:function(){return this.headers ['x-iisnode-remote_addr']; }
});
次();
});
この問題はついに解決されましたが、これは良い方法ではありません。 ExpressがReq.ipを将来読み取り専用に設定すると、面倒です。
テストを続け、別の問題を見つけます。通常、ブログのバックグラウンドのファイルアップロード関数はファイルをパブリック/アップロードディレクトリに渡しますが、実際、公開/アップロードフォルダーは起動ディレクトリ(つまり、元のBinディレクトリ)で生成されます。実際、その理由は、プログラムの入り口としてのWWWファイルが起動ディレクトリにあるため、起動ディレクトリがアプリケーションの実行ディレクトリになるためです。私の解決策は、起動ディレクトリの名前をBINに戻し、rooling.jsをルートディレクトリに作成して、bin/wwwを呼び出すことです。
コードコピーは次のとおりです。
#!/usr/bin/envノード
要求( './ bin/www');
次に、プログラムエントリをlaunch.jsに変更します。
コードコピーは次のとおりです。
<configuration>
<System.Webserver>
<ハンドラー>
<add name = "iisnode" path = "raunch.js" verb = "*" modules = "iisnode" resourcetype = "quensecified" requirecass = "script" />
</handlers>
<書き直し>
<rules>
<ルールname = "all">
<match url = " /*" />
<action type = "rewrite" url = "raunch.js" />
</rule>
</rules>
</書き換え>
<iisnode prosomeservervars = "remote_addr" />
</system.webserver>
</configuration>
明らかに、IISNodeは成熟した製品ではなく、もちろんnode.jsは(まだ1.0ではありません)、すべての調査と改善が必要です。