Zu Beginn dieses Jahres hatte ich vor, mein Blog -Programm basierend auf dem Express -Framework mit node.js neu zu schreiben und von nun an Abschied von ASP.NET zu veranschaulichen. Das VPS, das ich derzeit verwendet, ist jedoch Windows Server System und IIS Server. Wenn Express und IIS beide Port 80 hören, wird es offensichtliche Konflikte geben. Glücklicherweise gibt es eine Erweiterung namens iisnode, die Node.js -Programme an IIS hostet. Darüber hinaus bedeutet dies nach dem Hosting auch, dass verschiedene Funktionen in IIS verwendet werden können (Prozessmanagement, GZIP -Komprimierung, Protokollierung, Cache, Berechtigungssteuerung, Domänenname -Bindung usw.).
Um IISNode zu verwenden, müssen Sie installieren:
1.Node.js
2. IIS URL Rewrite Modul
3.iisnode
Nach der Installation folgen Sie weiterhin den üblichen Vorgängen, um eine Website im IIS -Manager zu erstellen und auf das Verzeichnis des Express -Programms zu verweisen. Der Schlüssel ist, eine Web.config -Datei hinzuzufügen:
Die Codekopie lautet wie folgt:
<Configuration>
<System.Webserver>
<Handler>
<add name = "iisnode" path = "bin /www" verb = "*" modules = "iisnode" ressourcetype = "unspezifiziert" Anforderung = "Skript" />
</Handler>
<RECHRITE>
<Regeln>
<regelname = "all">
<Match url = " /*" />
<action type = "neu schreiben" url = "bin /www" />
</regel>
</Regeln>
</umschreiben>
</Systems.Webserver>
</Konfiguration>
Dieser Inhalt kann auch über die visuelle Schnittstelle des IIS -Managers konfiguriert werden. Es bedeutet grob, alle Anfragen in Bin/www umzuschreiben und Bin/www mit der IISnode -Erweiterung auszuführen. Nach dem Öffnen der Site wird jedoch eine Fehlermeldung angezeigt:
Die Codekopie lautet wie folgt:
Das Anforderungsfiltermodul ist so konfiguriert, dass die Pfade in der URL, die den Abschnitt HiddenSegment enthalten
Zuerst hatte ich das Gefühl, dass ich nicht klar war, aber später stellte ich plötzlich fest, dass das Bin -Verzeichnis in ASP.NET ein spezielles Verzeichnis ist, auf das nicht zugegriffen werden darf. Schreiben Sie die Anfrage nach Bin/www neu, die diese Regel trifft. Ändern Sie also einfach den Verzeichnisnamen, beispielsweise den Bin in den Start (er stellt sich als keine gute Praxis heraus, sprechen wir später darüber), und Web.Config muss auch entsprechend angepasst werden:
Die Codekopie lautet wie folgt:
<Configuration>
<System.Webserver>
<Handler>
<add name = "iisnode" path = "starten /www" verb = "*" modules = "iisnode" ressourcetype = "unspezifiziert" Anforderungsverhältnis = "Skript" />
</Handler>
<RECHRITE>
<Regeln>
<regelname = "all">
<Match url = " /*" />
<action type = "rewrite" url = "starten /www" />
</regel>
</Regeln>
</umschreiben>
</Systems.Webserver>
</Konfiguration>
Nachdem sie die Website im IIS -Manager neu gestartet hatte und wieder auf sie zugab, begann sie endlich zu laufen, es war nicht einfach! Aber ich war immer noch zu glücklich.
Während des Tests der Programmfunktion wurde festgestellt, dass die erhaltene IP leer war. Im Express -Framework wird IP durch Req.ip erhalten, was wiederum den Wert von Remote_Addr des Anforderungsheaders erhält. Durch einen einfachen Testcode wurde festgestellt, dass der Wert von remote_addr ebenfalls leer ist. Es ist offensichtlich, dass diese Header -Informationen während des Prozesses von IIS zu Node.js. verloren gehen. Nach Google stellte ich fest, dass IisNode dieses Problem hat. Die offizielle Lösung besteht darin, X-Fach-Wort zu verwenden, aber ich habe eine andere Lösung gefunden.
In web.config (vor dem Hinzufügen zu </Systems.Webserver>) gibt es eine Konfiguration, die remote_addr beibehalten kann:
Die Codekopie lautet wie folgt:
<iisnode promoteServervars = "remote_addr" />
Gemäß den Anweisungen wird der reservierte Remote_ADDR in X-Iisnode-remote_addr umbenannt, sodass Sie den Wert von req.ip einmal überschreiben und der App.js von Express eine Middleware-Funktion hinzufügen müssen:
Die Codekopie lautet wie folgt:
app.use (function (req, res, next) {
req.ip = req.headers ['x-iisnode-remote_addr'];
nächste();
});
Nach dieser Anpassung ist die erhaltene IP jedoch immer noch leer, was sich unweigerlich fragen lässt, ob die Zuordnung von req.ip fehlgeschlagen ist. Wenn Sie sich den Quellcode von Express ansehen, werden Sie feststellen, dass Req.ip durch den Define Getter definiert wird. Um ihn also zu überschreiben, müssen Sie erneut definieren:
Die Codekopie lautet wie folgt:
app.use (function (req, res, next) {
Object.DefineProperty (req, 'ip', {{
get: function () {return this.headers ['x-iisnode-remote_addr']; }
});
nächste();
});
Dieses Problem wurde endlich gelöst, aber dies ist keine gute Methode. Es wird problematisch sein, wenn Express in Zukunft req.ip auf schreibgeschützte Sätze setzt.
Testen Sie weiter und finden Sie ein anderes Problem. Normalerweise wird die Datei -Upload -Funktion im Blog -Hintergrund die Datei an das Verzeichnis für das öffentliche/hochladen übergeben. Tatsächlich wird der Ordner für öffentliche/Upload im Startverzeichnis (dh im ursprünglichen Bin -Verzeichnis) generiert. Der Grund dafür ist, dass sich die WWW -Datei als Programmeingang im Startverzeichnis befindet, sodass das Startverzeichnis zum Ausführungsverzeichnis der Anwendung wird. Meine Lösung ist es, den Namen des Startverzeichnisses zurück in Bin zu ändern und einen Start.js im Stammverzeichnis zu erstellen, um Bin/www aufzurufen:
Die Codekopie lautet wie folgt:
#!/usr/bin/envknoten
erfordern ('./ bin/www');
Wechseln Sie dann den Programmeintrag in Start.js:
Die Codekopie lautet wie folgt:
<Configuration>
<System.Webserver>
<Handler>
<add name = "iisnode" path = "stirp.js" verb = "*" modules = "iisnode" ressourcetype = "nicht spezifiziert" forderaccess = "script" />
</Handler>
<RECHRITE>
<Regeln>
<regelname = "all">
<Match url = " /*" />
<action type = "rewrite" url = "stirp.js" />
</regel>
</Regeln>
</umschreiben>
<iisnode promoteServervars = "remote_addr" />
</Systems.Webserver>
</Konfiguration>
Offensichtlich ist IISNode kein ausgereiftes Produkt, und natürlich Node.js ist nicht (noch nicht 1.0), alles braucht weitere Erforschung und Verbesserung.