如何用Fiddler/Charles Proxy监控Next.js 14 App Router后端请求
解决Next.js 14 App Router中服务器端第三方请求的监控问题
下面给你几个直接可用的方案,无需依赖Next.js的rewrite功能:
方案1:封装带日志的请求工具函数
在项目中创建统一的请求封装文件,比如utils/fetchWithLogging.ts,所有Server Components和API路由都用这个函数发起第三方请求,开发环境自动打印请求细节:
export async function fetchWithLogging(input: RequestInfo | URL, init?: RequestInit) { // 仅在开发环境启用日志 if (process.env.NODE_ENV === 'development') { console.log('=== 第三方请求详情 ==='); console.log('请求方法:', init?.method || 'GET'); console.log('请求URL:', input.toString()); console.log('请求Headers:', init?.headers); if (init?.body) { console.log('请求Body:', init.body); } console.log('====================='); } return fetch(input, init); }
之后在Server Components或API路由里替换原生fetch:
import { fetchWithLogging } from '@/utils/fetchWithLogging'; // Server Component中使用 async function MyComponent() { const data = await fetchWithLogging('https://第三方API地址'); // ...业务逻辑 }
这个方案能直接在终端看到所有请求参数,排查起来直观高效。
方案2:配置Node.js代理让Charles捕获服务器端请求
Node.js默认不会走系统代理,导致服务器端的请求无法被Charles捕获。你可以在开发环境给fetch配置代理Agent,让请求走Charles:
首先安装代理依赖:
npm install --save-dev https-proxy-agent
创建代理配置文件utils/proxyAgent.ts:
import { HttpsProxyAgent } from 'https-proxy-agent'; export const getProxyAgent = () => { if (process.env.NODE_ENV === 'development') { // Charles默认代理地址为localhost:8888 return new HttpsProxyAgent('http://localhost:8888'); } return undefined; };
发起请求时带上Agent:
import { getProxyAgent } from '@/utils/proxyAgent'; async function fetchThirdPartyData() { const response = await fetch('https://第三方API地址', { agent: getProxyAgent(), // 其他请求配置 }); // ...业务逻辑 }
配置完成后,Charles就能捕获到服务器端发往第三方的请求,可直接查看参数、响应内容。
方案3:全局拦截Node.js请求
如果不想逐个替换fetch,可以用Node.js的http模块全局拦截请求。在next.config.js或项目服务器入口文件(比如app/_server.ts,需确保服务器启动时加载)添加:
import http from 'http'; if (process.env.NODE_ENV === 'development') { const originalRequest = http.request; http.request = function (options: http.RequestOptions | string | URL, callback?) { console.log('=== 全局拦截的HTTP请求 ==='); console.log('请求URL:', typeof options === 'string' ? options : `${options.host}${options.path}`); console.log('请求方法:', options.method); console.log('请求Headers:', options.headers); return originalRequest(options, callback); }; // 同样处理HTTPS请求 import https from 'https'; const originalHttpsRequest = https.request; https.request = function (options: https.RequestOptions | string | URL, callback?) { console.log('=== 全局拦截的HTTPS请求 ==='); console.log('请求URL:', typeof options === 'string' ? options : `${options.host}${options.path}`); console.log('请求方法:', options.method); console.log('请求Headers:', options.headers); return originalHttpsRequest(options, callback); }; }
这个方案无需修改业务代码,全局生效,但日志信息的详细度不如封装函数,适合快速排查场景。
内容的提问来源于stack exchange,提问作者P.Pras
相关产品推荐
相关产品推荐

