如何将Next.js中返回纯文本的路由中间件迁移至Blitz.js?
我明白你现在的困境:把Next.js的编程类网站迁到Blitz.js后,原本用_middleware.js实现的/script路由重写和参数处理逻辑不知道怎么适配。Blitz的中间件体系和Next.js App Router的确实不一样,下面给你两种可行的解决方案,你可以根据需求选择:
方案一:使用Blitz的Server Middleware(最贴近原逻辑)
Blitz基于Express风格的中间件体系,你需要把中间件放在src/server/middleware目录下,然后在配置文件中注册它:
1. 创建中间件文件
在src/server/middleware目录下新建scriptRedirect.js(如果没有这个目录就自己创建),写入以下代码:
// src/server/middleware/scriptRedirect.js export default function scriptRedirectMiddleware(req, res, next) { // 解析请求路径和查询参数 const url = new URL(req.url, `http://${req.headers.host}`); const { pathname } = url; if (pathname === '/script') { let version = parseInt(url.searchParams.get('v')); if (isNaN(version)) { version = 'latest'; } const params = version ? `?version=${version}` : ''; // 修改请求路径,转发到你的API路由 req.url = `/api/basic-script${params}`; return next(); } // 非目标路径,继续执行后续逻辑 next(); }
2. 在Blitz配置中注册中间件
打开blitz.config.js,添加serverMiddleware配置项:
// blitz.config.js const { default: createBlitzConfig } = require("@blitzjs/next"); module.exports = createBlitzConfig({ // 注册自定义中间件 serverMiddleware: [ require("./src/server/middleware/scriptRedirect.js").default, ], });
这样配置后,当用户访问/script?v=1时,中间件会自动把请求转发到/api/basic-script?version=1,和你原来的Next.js中间件逻辑完全一致。
方案二:合并逻辑到API路由(更简洁)
如果不想单独维护中间件,你可以直接把/script的逻辑合并到API路由里,再通过路由重写映射路径:
1. 创建/script对应的API路由
在src/pages/api下新建script.js,写入以下代码(注意显式设置Content-Type为text/plain):
// src/pages/api/script.js export default function handler(req, res) { let { v: version } = req.query; version = parseInt(version); if (isNaN(version)) { version = 'latest'; } // 确保返回text/plain格式 res.setHeader('Content-Type', 'text/plain'); res.status(200).send(`echo "This script doesn't do anything yet. (version: ${version})"`); }
2. 添加路由重写规则
在blitz.config.js中添加rewrites配置,把/script路径映射到这个API:
// blitz.config.js const { default: createBlitzConfig } = require("@blitzjs/next"); module.exports = createBlitzConfig({ async rewrites() { return [ { source: '/script', destination: '/api/script', }, ]; }, });
为什么原来的_middleware.js没用?
Blitz目前(v2.x版本)还不支持Next.js App Router风格的_middleware.js文件放在pages目录下,它的中间件体系是基于Express的serverMiddleware,所以你之前放在app/pages下的_middleware.js不会被加载,这也是为什么需要用上面两种方式的原因。
另外要注意,在Blitz的API路由里最好显式设置Content-Type为text/plain,确保cURL等工具能正确识别响应格式。
内容的提问来源于stack exchange,提问作者Sir Robert

