如何让Fastify部分路由使用不同的fastify-multipart配置?
解决方案
你可以通过分前缀注册fastify-multipart插件实现不同路由的差异化配置:
- 为全局路由(排除
/image/*)注册插件并启用addToBody: true - 单独为
/image/*前缀注册插件,禁用addToBody(不设置该选项或显式设为false)
插件注册代码
// 全局注册(跳过/image/*路由),开启addToBody app.register(require("fastify-multipart"), { addToBody: true, onRequest: (request, _, done) => { if (request.url.startsWith('/image/')) { done(new Error('skip')); // 跳过当前插件逻辑 } else { done(); } } }); // 为/image/*路由单独注册,禁用addToBody app.register(require("fastify-multipart"), { addToBody: false }, { prefix: '/image' });
路由定义保持不变
app.get("/health", (_, reply) => reply.send("Congratulations! reverse proxy is working.....")); app.route({ method: ["DELETE", "GET", "HEAD", "PATCH", "POST", "PUT"], url: "*", handler: handler, });
修复后的/image/upload处理函数
原处理函数存在几个潜在问题,调整后如下:
const FormData = require('form-data'); // 需要先安装form-data包 const handler = async (request, reply) => { const formData = new FormData(); let uploadError = null; return new Promise((resolve, reject) => { const multipart = request.multipart( (field, stream, filename, _, mimetype) => { // 传递文件信息给FormData formData.append('image', stream, { filename, mimetype }); }, (error) => { if (error) { uploadError = error; console.log(`Error uploading file: ${error.message}`); reply.code(500).send(); reject(error); } } ); // 等待multipart解析完成后再发送请求 multipart.on('end', async () => { if (uploadError) return; try { const config = { headers: { ...formData.getHeaders() } // 必须携带FormData的请求头 }; const data = await axios.post('http://127.0.0.1:80/downstream', formData, config); console.log("upload success with url", data); reply.send(data); resolve(data); } catch (e) { console.log(`An error occurred during upload: ${e.message}`); reply.code(500).send(); reject(e); } }); }); };
原理说明
- Fastify支持按路由前缀注册插件,不同前缀的插件配置相互独立,不会冲突
- 全局插件通过
onRequest钩子跳过/image/*路由的处理,避免干扰前缀插件的逻辑 /image/*路由下的插件禁用addToBody,保留原始multipart流,让request.multipart可以正常解析处理
内容的提问来源于stack exchange,提问作者Ashok Singh
相关产品推荐
相关产品推荐

