【Azure 應用服務】Azure Mobile App (NodeJS) 的服務端部署在App Service for Windows中出現404 Not Found — The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
- 2022 年 1 月 24 日
- 筆記
- 【Azure 應用服務】, App Service, NodeJS + Express, nodejs web.config, 解決node.js的404問題
問題描述
使用NodeJS的後端應用,開發一個Mobile App的服務端,手機端通過REST API來訪問獲取後端數據。在本地編譯好後,通過npm start啟動項目,訪問效果如下:

但是,當把項目文件通過FTP,或者直接VS Code 部署到App Service for windows後,訪問首頁並不是mobile app的頁面,而是默認的App Service頁面,訪問項目裡面的API也是404錯誤?

問題解決
從訪問默認URL和測試API為404的效果來看,這是NodeJS項目並沒有啟動。因為是App Service For Windows環境,非ASP.NET的項目都需要通過IIS啟用對於的進程文件來執行程式碼。如NodeJS項目則會啟動一個 node.exe 用於執行 js 文件。
所以第一步是進入到App Service的高級工具 (Kudu)站點中,查看以下圖片中的兩點:
1: node.exe 進程是否存在
2: node.exe 進程中所載入的js文件是否是正確的啟動文件

如果缺少了Web.config文件,則以下面的內容來創建它:
<?xml version="1.0" encoding="utf-8"?> <!-- This configuration file is required if iisnode is used to run node processes behind IIS or IIS Express. For more information, visit: //github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config --> <configuration> <system.webServer> <!-- Visit //blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support --> <webSocket enabled="false" /> <handlers> <!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module --> <add name="iisnode" path="app.js" verb="*" modules="iisnode"/> </handlers> <rewrite> <rules> <!-- Do not interfere with requests for node-inspector debugging --> <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true"> <match url="^app.js\/debug[\/]?" /> </rule> <!-- First we consider whether the incoming URL matches a physical file in the /public folder --> <rule name="StaticContent"> <action type="Rewrite" url="public{REQUEST_URI}"/> </rule> <!-- All other URLs are mapped to the node.js site entry point --> <rule name="DynamicContent"> <conditions> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/> </conditions> <action type="Rewrite" url="app.js"/> </rule> </rules> </rewrite> <!-- 'bin' directory has no special meaning in node.js and apps can be placed in it --> <security> <requestFiltering> <hiddenSegments> <remove segment="bin"/> </hiddenSegments> </requestFiltering> </security> <!-- Make sure error responses are left untouched --> <httpErrors existingResponse="PassThrough" /> <!-- You can control how Node is hosted within IIS using the following options: * watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server * node_env: will be propagated to node as NODE_ENV environment variable * debuggingEnabled - controls whether the built-in debugger is enabled See //github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options --> <!--<iisnode watchedFiles="web.config;*.js"/>--> </system.webServer> </configuration>
PS: handlers 和 rewrite 部分是必須的,其中 app.js 的名稱可以根據實際項目中的啟動文件而修改。
當web.config添加後,問題解決,再次訪問效果為:

附錄一:如果是遇見的其他錯誤,如 Module 缺少,則可以在 Logfiles中的 Application 文件夾中的 logging-errors.txt 中查看詳細錯誤,如:
Mon Jan 24 2022 10:59:28 GMT+0000 (Greenwich Mean Time): Application has thrown an uncaught exception and is terminated: Error: Cannot find module 'express' Require stack: - D:\home\site\wwwroot\index.js - D:\Program Files (x86)\iisnode\interceptor.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15) at Function.Module._load (internal/modules/cjs/loader.js:667:27) at Module.require (internal/modules/cjs/loader.js:887:19) at require (internal/modules/cjs/helpers.js:74:18) at Object.<anonymous> (D:\home\site\wwwroot\index.js:1:17) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Module.require (internal/modules/cjs/loader.js:887:19) Mon Jan 24 2022 11:09:37 GMT+0000 (Greenwich Mean Time): Application has thrown an uncaught exception and is terminated: Error: Cannot find module 'depd' Require stack: - D:\home\site\wwwroot\node_modules\body-parser\index.js - D:\home\site\wwwroot\node_modules\express\lib\express.js - D:\home\site\wwwroot\node_modules\express\index.js - D:\home\site\wwwroot\index.js - D:\Program Files (x86)\iisnode\interceptor.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15) at Function.Module._load (internal/modules/cjs/loader.js:667:27) at Module.require (internal/modules/cjs/loader.js:887:19) at require (internal/modules/cjs/helpers.js:74:18) at Object.<anonymous> (D:\home\site\wwwroot\node_modules\body-parser\index.js:14:17) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Module.require (internal/modules/cjs/loader.js:887:19) Mon Jan 24 2022 11:10:24 GMT+0000 (Greenwich Mean Time): Application has thrown an uncaught exception and is terminated: Error: Cannot find module 'merge-descriptors' Require stack: - D:\home\site\wwwroot\node_modules\express\lib\express.js - D:\home\site\wwwroot\node_modules\express\index.js - D:\home\site\wwwroot\index.js - D:\Program Files (x86)\iisnode\interceptor.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15) at Function.Module._load (internal/modules/cjs/loader.js:667:27) at Module.require (internal/modules/cjs/loader.js:887:19) at require (internal/modules/cjs/helpers.js:74:18) at Object.<anonymous> (D:\home\site\wwwroot\node_modules\express\lib\express.js:17:13) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Module.require (internal/modules/cjs/loader.js:887:19) Mon Jan 24 2022 11:11:35 GMT+0000 (Greenwich Mean Time): Application has thrown an uncaught exception and is terminated: Error: Cannot find module 'finalhandler' Require stack: - D:\home\site\wwwroot\node_modules\express\lib\application.js - D:\home\site\wwwroot\node_modules\express\lib\express.js - D:\home\site\wwwroot\node_modules\express\index.js - D:\home\site\wwwroot\index.js - D:\Program Files (x86)\iisnode\interceptor.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15) at Function.Module._load (internal/modules/cjs/loader.js:667:27) at Module.require (internal/modules/cjs/loader.js:887:19) at require (internal/modules/cjs/helpers.js:74:18) at Object.<anonymous> (D:\home\site\wwwroot\node_modules\express\lib\application.js:16:20) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Module.require (internal/modules/cjs/loader.js:887:19)
然後,直接從本地項目文件夾 node_modules 中的內容 上傳到 App Service 中,即可解決 connot find module 『 **** 』 錯誤。
附錄二:示例程式碼
下載地址://files.cnblogs.com/files/lulight/nodejs-express-azuermobileapp-web.confg.zip?t=1643031258
參考資料
Create a Node.js web app in Azure://docs.microsoft.com/en-us/azure/app-service/quickstart-nodejs?tabs=windows&pivots=development-environment-vscode
Node.js Hello World in App Service: //github.com/Azure-Samples/nodejs-docs-hello-world


