如题,项目前端是nuxt2做的,现在遇到如下问题 当通过非正常编码编码后的url 访问的时候, pm2日志中报错 "URI malformed" 探究了一下,错误是因为 /node_moduels/@nuxt/server/dist/server.js 文件中的 const nuxtMiddleware = ({ options, nuxt, renderRoute, resources }) => async function nuxtMiddleware (req, res, next) { // Get context const context = utils.getContext(req, res); try { const url = decodeURI(req.url); //这里 res.statusCode = 200; const result = await renderRoute(url, context); // If result is falsy, call renderLoading if (!result) { await nuxt.callHook('server:nuxt:renderLoading', req, res); return } await nuxt.callHook('render:route', url, result, context); const { html, cspScriptSrcHashes, error, redirected, preloadFiles } = result; if (redirected && context.target !== utils.TARGETS.static) { await nuxt.callHook('render:routeDone', url, result, context); return html } if (error) { res.statusCode = context.nuxt.error.statusCode || 500; } if (options.render.csp && cspScriptSrcHashes) { const { allowedSources, policies } = options.render.csp; const isReportOnly = !!options.render.csp.reportOnly; const cspHeader = isReportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy'; res.setHeader(cspHeader, getCspString({ cspScriptSrcHashes, allowedSources, policies, isReportOnly })); } // Add ETag header if (!error && options.render.etag) { const { hash } = options.render.etag; const etag = hash ? hash(html, options.render.etag) : generateETag__default['default'](html, options.render.etag); if (fresh__default['default'](req.headers, { etag })) { res.statusCode = 304; await nuxt.callHook('render:beforeResponse', url, result, context); res.end(); await nuxt.callHook('render:routeDone', url, result, context); return } res.setHeader('ETag', etag); } // HTTP2 push headers for preload assets if (!error && options.render.http2.push) { // Parse resourceHints to extract HTTP.2 prefetch/push headers // https://w3c.github.io/preload/#server-push-http-2 const { shouldPush, pushAssets } = options.render.http2; const { publicPath } = resources.clientManifest; const links = pushAssets ? pushAssets(req, res, publicPath, preloadFiles) : defaultPushAssets(preloadFiles, shouldPush, publicPath, options); // Pass with single Link header // https://blog.cloudflare.com/http-2-server-push-with-multiple-assets-per-link-header // https://www.w3.org/Protocols/9707-link-header.html if (links.length > 0) { res.setHeader('Link', links.join(', ')); } } // Send response res.setHeader('Content-Type', 'text/html; charset=utf-8'); res.setHeader('Accept-Ranges', 'none'); // #3870 res.setHeader('Content-Length', Buffer.byteLength(html)); await nuxt.callHook('render:beforeResponse', url, result, context); res.end(html, 'utf8'); await nuxt.callHook('render:routeDone', url, result, context); return html } catch (err) { if (context && context.redirected) { consola__default['default'].error(err); return err } if (err.name === 'URIError') { //这里 err.statusCode = 400; } next(err); } }; 其中 const url = decodeURI(req.url); 对url无法进行解析,导致的. **需求是想在遇到"URI malformed"错误的时候,直接跳首页,目前采用了两种做法解决** #### 第一种: 在nuxt.config.js文件中,增加 serverMiddleware 配置项 serverMiddleware: [ (req, res, next) => { // 自定义中间件逻辑... try { //尝试解析url decodeURIComponent(req.url) //往下继续执行 next(); } catch { //解析错误就跳转 res.writeHead(302, { Location: '/' }); res.end(); } } ], 这样可以解决,但是无法阻止server.js 文件会对url再次进行解析,这样比较消耗资源 #### 第二种: 直接修改 /node_moduels/@nuxt/server/dist/server.js 文件 在 if (err.name === 'URIError') { err.statusCode = 400; } 中加入: if (err.name === 'URIError') { err.statusCode = 400; //新加 res.writeHead(302, { Location: '/' }) //新加 return res.end() } 这样也能起到效果,但是这样就直接修改了核心代码 #### 第三种: 使用nuxt.config.js 中的hook,示例如下 hooks: { render: { errorMiddleware(app) { app.use((error, req, res, next) => { res.writeHead(302, { Location: '/', }) res.end() }) }, }, 这样也可以,似乎更恰当一些 但是对于负载来说, 是重定向到首页好,还是直接返回错误页,还是直接返回错误提示更好呢?