Express部署Angular时路由跳转正常,刷新/直接访问URL报错崩溃
Angular路由刷新/直接访问时Express服务器报错问题
问题现象
使用Express服务器运行Angular应用时,页面内路由跳转完全正常,但跳转到某路由后刷新页面,或直接在地址栏输入该路由URL时,服务器返回“Internal Server Error”;第二次执行刷新操作时,服务器会直接崩溃。
服务器报错日志
第一次刷新时的报错
Error at XMLHttpRequest3.send (/Users/<path-to>/server/main.js:1:4025798) at Observable._subscribe (/Users/<path-to>/server/main.js:1:4264955) at Observable._trySubscribe (/Users/<path-to>/server/main.js:1:3520438) at Observable.subscribe (/Users/<path-to>/server/main.js:1:3520220) at DoOperator.call (/Users/<path-to>/server/main.js:1:3583421) at Observable.subscribe (/Users/<path-to>/server/main.js:1:3520074) at CatchOperator.call (/Users/<path-to>/server/main.js:1:3562760) at Observable.subscribe (/Users/<path-to>/server/main.js:1:3520074) at scheduleTask (/Users/<path-to>/main.js:1:640743) at Observable._subscribe (/Users/<path-to>/server/main.js:1:641346) 未处理的Promise拒绝: req.next is not a function ; Zone: <root> ; Task: Promise.then ; Value: TypeError: req.next is not a function at done (/Users/<path-to>/server/main.js:1:2200666) at _ZoneDelegate2.invoke (/Users/<path-to>/server/main.js:1:4048589) at Zone3.run (/Users/<path-to>/server/main.js:1:4040924) at /Users/<path-to>/server/main.js:1:4068136 at _ZoneDelegate2.invokeTask (/Users/<path-to>/server/main.js:1:4049527) at Zone3.runTask (/Users/<path-to>/main.js:1:4042009) at drainMicroTaskQueue (/Users/<path-to>/server/main.js:1:4053298) TypeError: req.next is not a function at done (/Users/<path-to>/server/main.js:1:2200666) at _ZoneDelegate2.invoke (/Users/<path-to>/server/main.js:1:4048589) at Zone3.run (/Users/<path-to>/server/main.js:1:4040924) at /Users/<path-to>/server/main.js:1:4068136 at _ZoneDelegate2.invokeTask (/Users/<path-to>/server/main.js:1:4049527) at Zone3.runTask (/Users/<path-to>/server/main.js:1:4042009) at drainMicroTaskQueue (/Users/<path-to>/server/main.js:1:4053298)
第二次刷新时服务器崩溃报错
/Users/<path-to>/server/main.js:1 var __defProp=Object.defineProperty,__name=(target,value)=>__defProp(target,"name",{value,configurable:!0});(()=>{var __webpack_modules__={12560:(module2,__webpack_exports__2,__webpack_require__2)=>{"use strict";__webpack_require__2.r(__webpack_exports__2),__webpack_require__2.d(__webpack_exports__2,{AppServerModule:()=>AppServerModule,app:()=>app,renderModule:()=>renderModule,renderModuleFactory:()=>renderModuleFactory});var transports_namespaceObject={};__webpack_require__2.r(transports_namespaceObject),__webpack_require__2.d(transports_namespaceObject,{BaseTransport:()=>BaseTransport,HTTPSTransport:()=>HTTPSTransport,HTTPTransport:()=>HTTPTransport,makeNodeTransport:()=>makeNodeTransport});var integrations_namespaceObject={};__webpack_require__2.r(integrations_namespaceObject),__webpack_require__2.d(integrations_namespaceObject,{Console:()=>Console,ContextLines:()=>ContextLines,Http:()=>Http,LinkedErrors:()=>LinkedErrors,Modules:()=>Modules,OnUncaughtException:()=>OnUncaughtException,OnUnhandledRejection:()=>OnUnhandledRejection});var esm_integrations_namespaceObject={};__webpack_require__2.r(esm_integrations_namespaceObject),__webpack_require__2.d(esm_integrations_namespaceObject,{FunctionToString:()=>FunctionToString,InboundFilters:()=>InboundFilters});var handlers_namespaceObject={};__webpack_require__2.r(handlers_namespaceObject),__webpack_require__2.d(handlers_namespaceObject,{errorHandler:()=>errorHandler,extractRequestData:()=>extractRequestData,parseRequest:()=>parseRequest,requestHandler:()=>requestHandler,tracingHandler:()=>tracingHandler});var node_esm_namespaceObject={};__webpack_require__2.r(node_esm_namespaceObject),__webpack_require__2.d(node_esm_namespaceObject,{Handlers:()=>handlers_namespaceObject,Hub:()=>Hub,Integrations:()=>INTEGRATIONS,NodeBackend:()=>NodeBackend,NodeClient:()=>NodeClient,SDK_NAME:()=>SDK_NAME,SDK_VERSION:()=>SDK_VERSION,Scope:()=>scope_Scope,Session:()=>Session,Severity:()=>Severity,Transports:()=>transports_namespaceObject,addBreadcrumb:()=>addBreadcrumb,addGlobalEventProcessor:()=>addGlobalEventProcessor,captureEvent:()=>captureEvent,captureException:()=>captureException,captureMessage:()=>captureMessage,close:()=>sdk_close,configureScope:()=>configureScope,deepReadDirSync:()=>deepReadDirSync,defaultIntegrations:()=>defaultIntegrations,flush:()=>flush,getCurrentHub:()=>getCurrentHub,getHubFromCarrier:()=>getHubFromCarrier,getSentryRelease:()=>getSentryRelease,init:()=>init,lastEventId:()=>lastEventId,makeMain:()=>makeMain,setContext:()=>setContext,setExtra:()=>setExtra,setExtras:()=>setExtras,setTag:()=>setTag,setTags:()=>setTags,setUser:()=>setUser,startTransaction:()=>startTransaction,withScope:()=>withScope});var integrations_namespaceObject_0={};__webpack_require__2.r(integrations_namespaceObject_0),__webpack_require__2.d(integrations_namespaceObject_0,{FunctionToString:()=>functiontostring_FunctionToString,InboundFilters:()=>inboundfilters_InboundFilters});var browser_esm_integrations_namespaceObject={};__webpack_require__2.r(browser_esm_integrations_namespaceObject),__webpack_require__2.d(browser_esm_integrations_namespaceObject,{Breadcrumbs:()=>Breadcrumbs,Dedupe:()=>Dedupe,GlobalHandlers:()=>GlobalHandlers,LinkedErrors:()=>linkederrors_LinkedErrors,TryCatch:()=>TryCatch,UserAgent:()=>UserAgent});var esm_transports_namespaceObject={};__webpack_require__2.r(esm_transports_namespaceObject),__webpack_require__2.d(esm_transports_namespaceObject,{BaseTransport:()=>base_BaseTransport,FetchTransport:()=>FetchTransport,XHRTransport:()=>XHRTransport,makeNewFetchTransport:()=>makeNewFetchTransport,makeNewXHRTransport:()=>makeNewXHRTransport});var browser_esm_namespaceObject={};__webpack_require__2.r(browser_esm_namespaceObject),__webpack_require__2.d(browser_esm_namespaceObject,{BrowserClient:()=>BrowserClient,Hub:()=>hub_Hub,Integrations:()=>esm_INTEGRATIONS,SDK_NAME:()=>version_SDK_NAME,SDK_VERSION:()=>version_SDK_VERSION,Scope:()=>scope_Scope_0,Session:()=>session_Session,Severity:()=>severity_Severity,Transports:()=>esm_transports_namespaceObject,addBreadcrumb:()=>minimal_addBreadcrumb,addGlobalEventProcessor:()=>scope_addGlobalEventProcessor,captureEvent:()=>minimal_captureEvent,captureException:()=>minimal_captureException,captureMessage:()=>minimal_captureMessage,close:()=>esm_sdk_close,configureScope:()=>minimal_configureScope,defaultIntegrations:()=>sdk_defaultIntegrations,eventFromException:()=>eventFromException,eventFromMessage:()=>eventbuilder_eventFromMessage,flush:()=>sdk_flush,forceLoad:()=>forceLoad,getCurrentHub:()=>hub_getCurrentHub,getHubFromCarrier:()=>hub_getHubFromCarrier,init:()=>sdk_init,injectReportDialog:()=>injectReportDialog,lastEventId:()=>sdk_lastEventId,makeMain:()=>hub_makeMain,onLoad:()=>onLoad,setContext:()=>minimal_setContext,setExtra:()=>minimal_setExtra,setExtras:()=>minimal_setExtras,setTag:()=>minimal_setTag,setTags:()=>minimal_setTags,setUser:()=>minimal_setUser,showReportDialog:()=>showReportDialog,startTransaction:()=>minimal_startTransaction,withScope:()=>minimal_withScope,wrap:()=>sdk_wrap});__webpack_require__2(97584);var TagContentType,TagContentType2,tslib_es6=__webpack_require__2(70655);function splitNsName(elementName){if(":"!=elementName[0])return[null,elementName];const colonIndex=elementName.indexOf(":",1);if(-1===colonIndex)throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);return[elementName.slice(1,colonIndex),elementName.slice(colonIndex+1)]}function isNgContainer(tagName){return"ng-container"===splitNsName(tagName)[1]}function isNgContent(tagName){return"ng-content"===splitNsName(tagName)[1]}function isNgTemplate(tagName){return"ng-template"===splitNsName(tagName)[1]}function getNsPrefix(fullName){return null===fullName?null:splitNsName(fullName)[0]}function mergeNsAndName(prefix,localName){return prefix?`:${prefix}:${localName}`:localName}(TagContentType2=TagContentType||(TagContentType={}))[TagContentType2.RAW_TEXT=0]="RAW_TEXT",TagContentType2[TagContentType2.ESCAPABLE_RAW_TEXT=1]="ESCAPABLE_RAW_TEXT",TagContentType2[TagContentType2.PARSABLE_DATA=2]="PARSABLE_DATA",__name(splitNsName,"splitNsName"),__name(isNgContainer,"isNgContainer"),__name(isNgContent,"isNgContent"),__name(isNgTemplate,"isNgTemplate"),__name(getNsPrefix,"getNsPrefix"),__name(mergeNsAndName,"mergeNsAndName");class HtmlTagDefinition{constructor({closedByChildren,implicitNamespacePrefix,contentType=TagContentType.PARSABLE_DATA,closedByParent=!1,isVoid=!1,ignoreFirstLf=!1,preventNamespaceInheritance=!1}={}){this.closedByChildren={},this.closedByParent=!1,this.canSelfClose=!1,closedByChildren&&closedByChildren.length>0&&closedByChildren.forEach(tagName=>this.closedByChildren[tagName]=!0),this.isVoid=isVoid,this.closedByParent=closedByParent||isVoid,this.implicitNamespacePrefix=implicitNamespacePrefix||null,this.contentType=contentType,this.ignoreFirstLf=ignoreFirstLf,this.preventNamespaceInheritance=preventNamespaceInheritance}isClosedByChild(name){return this.isVoid||name.toLowerCase()in this.closedByChildren}getContentType(prefix){if("object"==typeof this.contentType){const overrideType=void 0===prefix?void 0:this.contentType[prefix];return null!=overrideType?overrideType:this.contentType.default}return this.contentType}}let _DEFAULT_TAG_DEFINITION,TAG_DEFINITIONS;function getHtmlTagDefinition(tagName){var _a,_b;return TAG_DEFINITIONS||(_DEFAULT_TAG_DEFINITION=new HtmlTagDefinition,TAG_DEFINITIONS={base:new HtmlTagDefinition({isVoid:!0}),meta:new HtmlTagDefinition({isVoid:!0}),area:new HtmlTagDefinition({isVoid:!0}),embed:new HtmlTagDefinition({isVoid:!0}),link:new HtmlTagDefinition({isVoid:!0}),img:new HtmlTagDefinition({isVoid:!0}),input:new HtmlTagDefinition({isVoid:!0}),param:new HtmlTagDefinition({isVoid:!0}),hr:new HtmlTagDefinition({isVoid:!0}),br:new HtmlTagDefinition({isVoid:!0}),source:new HtmlTagDefinition({isVoid:!0}),track:new HtmlTagDefinition({isVoid:!0}),wbr:new HtmlTagDefinition({isVoid:!0}),p:new HtmlTagDefinition({closedByChildren:["address","article","aside","blockquote","div","dl","fieldset","footer","form","h1","h2","h3","h4","h5" 服务器发生错误。 node 退出,代码为 1。
解决方案
1. 让Express接管所有前端路由请求
Angular是单页应用,前端路由由Angular Router处理,刷新或直接访问路由时,请求会发送到Express服务器,此时需要让服务器返回Angular的入口文件index.html,由Angular处理路由:
const express = require('express'); const path = require('path'); const app = express(); // 指向Angular编译后的静态资源目录 app.use(express.static(path.join(__dirname, 'dist/你的Angular应用名称'))); // 所有非API请求返回index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist/你的Angular应用名称/index.html')); }); const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`服务器运行在端口 ${port}`); });
替换代码中的你的Angular应用名称为实际项目名称。
2. 修复req.next错误
报错中的TypeError: req.next is not a function是因为中间件使用错误:
- 检查所有Express中间件函数,确保它们正确接收
req, res, next三个参数 - 不要在非中间件函数中调用
req.next() - 排查第三方中间件是否存在版本兼容问题,尝试更新依赖
3. 添加全局错误处理防止服务器崩溃
为Express添加全局错误处理中间件,捕获未处理的异常和Promise拒绝:
// 全局错误处理中间件 app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('服务器内部错误'); }); // 捕获未处理的Promise拒绝 process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', promise, '原因:', reason); // 可根据需要添加自定义处理逻辑 });
内容的提问来源于stack exchange,提问作者larschla
相关产品推荐
相关产品推荐

