A principios de este año, planeaba reescribir mi programa de blog basado en el marco Express usando Node.js, y decir adiós a ASP.NET de ahora en adelante. Sin embargo, el VPS que uso actualmente es Windows Server System y IIS Server. Si Express e IIS escuchan el puerto 80, habrá conflictos obvios. Afortunadamente, hay una extensión llamada IISNode que aloja los programas Node.js a IIS. Además, después del alojamiento, también significa que se pueden utilizar varias funciones en IIS (administración de procesos, compresión de GZIP, registro, caché, control de permiso, enlace de nombres de dominio, etc.).
Para usar IISNode, debe instalar:
1.node.js
2. Módulo de reescritura de IIS URL
3.iisnode
Después de la instalación, aún sigue las operaciones habituales para crear un sitio en el Administrador de IIS y señalar el directorio del programa Express. La clave es agregar un archivo web.config:
La copia del código es la siguiente:
<Configuración>
<System.WebServer>
<manejadores>
<add name = "iisnode" path = "bin /www" verb = "*" módulos = "iisnode" resurceType = "no especificado" requireAccess = "script" />
</axers>
<REWRITE>
<reglas>
<nombre de regla = "all">
<Match url = " /*" />
<Action type = "Rewrite" url = "bin /www" />
</regla>
</reglas>
</reescritura>
</system.webserver>
</figuration>
Este contenido también se puede configurar a través de la interfaz visual del Administrador de IIS. Significa aproximadamente reescribir todas las solicitudes a bin/www, y ejecutar bin/www usando la extensión IISNODE. Sin embargo, después de abrir el sitio, aparece un mensaje de error:
La copia del código es la siguiente:
El módulo de filtro de solicitud está configurado para rechazar las rutas en la URL que contiene la sección HidenDenDengment
Al principio sentí que no tenía claro, pero luego de repente me di cuenta de que el directorio bin en ASP.NET es un directorio especial al que no se permite acceder. Reescribe la solicitud a bin/www, que golpea esta regla. Entonces, solo cambie el nombre del directorio, por ejemplo, cambie a Bin para que se inicie (resulta que no es una buena práctica, hablemos de ello más tarde), y Web.Config también debe ajustarse en consecuencia:
La copia del código es la siguiente:
<Configuración>
<System.WebServer>
<manejadores>
<add name = "iisnode" path = "unch /www "verb ="*"módulos =" iisnode "resurceType =" sin especificar "requireAccess =" script " />
</axers>
<REWRITE>
<reglas>
<nombre de regla = "all">
<Match url = " /*" />
<Action type = "Rewrite" url = "unch /www " />
</regla>
</reglas>
</reescritura>
</system.webserver>
</figuration>
Después de reiniciar el sitio en IIS Manager, accediendo a él nuevamente, finalmente comenzó a funcionar, ¡no fue fácil! Pero todavía estaba demasiado feliz.
Durante el proceso de prueba de la función del programa, se descubrió que la IP obtenida estaba vacía. En el marco Express, IP se obtiene a través de req.ip, que a su vez obtiene el valor de remota_addr del encabezado de solicitud. A través de un código de prueba simple, se descubrió que el valor de Remote_Addr también está vacío. Es obvio que esta información del encabezado se pierde durante el proceso de II a Node.js. Después de Google, descubrí que IISNode tiene este problema. La solución oficial es usar X-Forword-For, pero encontré otra solución.
Hay una configuración en Web.config (antes de agregarla a </system.webserver>) que puede retener remoto_addr:
La copia del código es la siguiente:
<iIsNode PromoteserverVars = "remoto_addr" />
De acuerdo con las instrucciones, el remoto_addr reservado se cambiará el nombre a X-iisnode-remote_addr, por lo que debe sobrescribir el valor de req.ip una vez y agregar una función de middleware a las aplicaciones de express:
La copia del código es la siguiente:
app.use (function (req, res, next) {
req.ip = req.headers ['x-iisnode-remote_addr'];
próximo();
});
Sin embargo, después de este ajuste, la IP obtenida todavía está vacía, lo que inevitablemente hace que la gente se pregunte si la asignación de REQ.IP ha fallado. Mirando el código fuente de Express, encontrará que REQ.IP se define a través del Getter Define, por lo que para sobrescribirlo, debe definir nuevamente:
La copia del código es la siguiente:
app.use (function (req, res, next) {
Objeto.defineProperty (req, 'ip', {
get: function () {return this.headers ['x-iisnode-remote_addr']; }
});
próximo();
});
Este problema finalmente se ha resuelto, pero este no es un buen método. Será problemático si Express establece req.ip a solo lectura en el futuro.
Continúe probando y encuentre otro problema. Normalmente, la función de carga de archivos en el fondo del blog pasará el archivo al directorio público/de carga, pero de hecho, la carpeta pública/cargada se genera en el directorio de lanzamiento (es decir, el directorio bin original). De hecho, la razón es que el archivo www como entrada del programa se encuentra en el directorio de lanzamiento, por lo que el directorio de lanzamiento se convierte en el directorio de ejecución de la aplicación. Mi solución es cambiar el nombre del directorio de lanzamiento de nuevo a bin, crear un lanzamiento.js en el directorio raíz para llamar a bin/www:
La copia del código es la siguiente:
#!/usr/bin/env nodo
requiere ('./ bin/www');
Luego cambie la entrada del programa a la elunch.js:
La copia del código es la siguiente:
<Configuración>
<System.WebServer>
<manejadores>
<Agregar name = "iisnode" path = "unch.js "verb ="*"módulos =" iisnode "resurceType =" sin especificar "requireAccess =" script " />
</axers>
<REWRITE>
<reglas>
<nombre de regla = "all">
<Match url = " /*" />
<Action type = "rewrite" url = "unch.js " />
</regla>
</reglas>
</reescritura>
<iIsNode PromoteserverVars = "remoto_addr" />
</system.webserver>
</figuration>
Obviamente, IISNode no es un producto maduro y, por supuesto, Node.js no es (no 1.0 todavía), todo necesita una mayor exploración y mejora.