如何通过IISNode在IIS上部署Node Express+React前端项目
问题描述
项目已进入收尾阶段,现有一个基于NodeJS Express运行的网站,可提供构建后的create-react-app前端服务。需通过IISNode将其配置在IIS上运行(服务器为Windows Server 2012 R2、IIS 8),目标是无需用户登录,只要服务器运行即可访问站点。
已尝试多种方案但未成功:
- Node监听
process.env.PORT || 8000,直接通过node运行(npm run start)无问题,但通过IIS运行时无法找到后端URL; - 将React作为独立站点运行时,初始API请求出现404错误;将前端托管在public文件夹时,出现403.14:无法列出目录内容的错误。
怀疑web.config是问题所在,已附上/bin/www文件及初始web.config内容。后续调整web.config启用rewrite规则指向/app.js后,出现500.1002内部服务器错误,提示iisnode无法捕获node.exe的输出日志,已给所有路径添加Everyone完全权限,仍未解决,且尝试在app.js中用try/catch写入日志也无效,推测未执行到app.js代码。
请告知还需提供哪些信息以解决问题。
附相关代码
/bin/www
#!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var debug = require('debug')('node-backend:server'); var http = require('http'); /** * Get port from environment and store in Express. */ var port = normalizePort(process.env.PORT || '8000'); app.set('port', port); /** * Create HTTP server. */ var server = http.createServer(app); /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); console.log('Listening on ' + bind); }
初始web.config
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers> <add name="iisnode" path="app.js" verb="*" modules="iisnode" /> </handlers> <!-- Removed in an effort to get a valid URL response --> <!-- <rewrite> <rules> <rule name="api"> <match url="/*" /> <action type="Rewrite" url="/*:8000" /> </rule> </rules> </rewrite> --> <security> <requestFiltering> <hiddenSegments> <add segment="node_modules" /> </hiddenSegments> </requestFiltering> </security> </system.webServer> </configuration>
更新后的web.config
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers accessPolicy="Execute"> <add name="iisnode" path="app.js" verb="*" modules="iisnode" resourceType="Either" requireAccess="Execute" /> </handlers> <rewrite> <rules> <rule name="api"> <match url="/*" /> <action type="Rewrite" url="/app.js/*" /> </rule> </rules> </rewrite> <security> <requestFiltering> <hiddenSegments> <add segment="node_modules" /> </hiddenSegments> </requestFiltering> </security> <tracing> <traceFailedRequests> <add path="*"> <traceAreas> <add provider="ISAPI Extension" verbosity="Verbose" /> <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI,WebSocket,ANCM,Rewrite,RequestRouting,iisnode" verbosity="Verbose" /> </traceAreas> <failureDefinitions statusCodes="403.14" verbosity="Warning" /> </add> </traceFailedRequests> </tracing> <iisnode watchedFiles="*.js" loggingEnabled="true" logDirectory="iisnode" devErrorsEnabled="true" /> </system.webServer> </configuration>
需要补充的信息
- IISNode版本号,以及服务器上Node.js的安装版本和安装路径;
- IIS站点的物理路径设置,确认是否指向项目根目录;
- app.js完整代码,尤其是静态文件托管、路由配置部分;
- 构建后React文件的存放路径,以及Express中是否配置了对应静态文件服务;
- 服务器上iisnode日志目录(即web.config中配置的
iisnode文件夹)下的日志内容(若有生成); - IIS应用程序池配置:包括.NET CLR版本(需设为
无托管代码)、运行身份(是否使用本地系统或权限足够的账户); - 访问站点时浏览器控制台的具体错误信息,以及IIS日志中的详细错误记录(可在IIS管理器站点日志中查看)。
内容的提问来源于stack exchange,提问作者Geoff
相关产品推荐
相关产品推荐

