diff --git a/apps/koa-esm/src/index.js b/apps/koa-esm/src/index.js index b001bc1..e96a2a0 100644 --- a/apps/koa-esm/src/index.js +++ b/apps/koa-esm/src/index.js @@ -77,6 +77,45 @@ router.get('/fetch', async (ctx) => { ctx.body = data }) +// Test case 1: text/plain + JSON body +router.get('/post-text-plain', async (ctx) => { + const res = await axios.post( + 'https://jsonplaceholder.typicode.com/posts', + JSON.stringify({ title: 'foo', body: 'bar', userId: 1 }), + { headers: { 'Content-Type': 'text/plain' } } + ) + ctx.body = res.data +}) + +// Test case 2: application/x-www-form-urlencoded +router.get('/post-form', async (ctx) => { + const res = await axios.post( + 'https://jsonplaceholder.typicode.com/posts', + 'title=foo&body=bar&userId=1', + { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } + ) + ctx.body = res.data +}) + +// Test case 3: pure text body +router.get('/post-pure-text', async (ctx) => { + const res = await axios.post( + 'https://jsonplaceholder.typicode.com/posts', + 'This is a plain text message', + { headers: { 'Content-Type': 'text/plain' } } + ) + ctx.body = res.data +}) + +// Test case 4: Buffer body +router.get('/post-buffer', async (ctx) => { + const buffer = Buffer.from(JSON.stringify({ title: 'buffer', body: 'test', userId: 1 })) + const res = await axios.post('https://jsonplaceholder.typicode.com/posts', buffer, { + headers: { 'Content-Type': 'application/json' } + }) + ctx.body = res.data +}) + // SSE test endpoint - server side router.get('/sse-server', async (ctx) => { ctx.set('Content-Type', 'text/event-stream') @@ -90,7 +129,9 @@ router.get('/sse-server', async (ctx) => { let count = 0 const interval = setInterval(() => { count++ - res.write(`event: message\nid: ${count}\ndata: {"count": ${count}, "time": "${new Date().toISOString()}"}\n\n`) + res.write( + `event: message\nid: ${count}\ndata: {"count": ${count}, "time": "${new Date().toISOString()}"}\n\n` + ) if (count >= 5) { clearInterval(interval) res.end() @@ -102,18 +143,18 @@ router.get('/sse-server', async (ctx) => { router.get('/sse-fetch', async (ctx) => { // Fetch SSE from our own server const response = await fetch('http://localhost:3001/sse-server') - + // Consume the stream to capture events const reader = response.body.getReader() const decoder = new TextDecoder() let result = '' - + while (true) { const { done, value } = await reader.read() if (done) break result += decoder.decode(value, { stream: true }) } - + ctx.body = { message: 'SSE stream consumed', data: result } }) diff --git a/packages/network-debugger/src/core/request.ts b/packages/network-debugger/src/core/request.ts index c6174ab..a07b611 100644 --- a/packages/network-debugger/src/core/request.ts +++ b/packages/network-debugger/src/core/request.ts @@ -22,10 +22,23 @@ function proxyClientRequestFactory( ) { const actualFn = actualRequest.write actualRequest.write = (data: any) => { - try { - requestDetail.requestData = JSON.parse(data.toString()) - } catch (err) { - requestDetail.requestData = data + // Convert to string at source to avoid IPC serialization issues + // Accumulate multiple writes (e.g., multipart/form-data) + let chunk: string + if (Buffer.isBuffer(data)) { + chunk = data.toString('utf-8') + } else if (typeof data === 'string') { + chunk = data + } else if (data != null) { + chunk = JSON.stringify(data) + } else { + chunk = '' + } + + if (requestDetail.requestData) { + requestDetail.requestData += chunk + } else { + requestDetail.requestData = chunk } return actualFn.bind(actualRequest)(data) diff --git a/packages/network-debugger/src/fork/module/network/index.ts b/packages/network-debugger/src/fork/module/network/index.ts index 73f229a..935f62a 100644 --- a/packages/network-debugger/src/fork/module/network/index.ts +++ b/packages/network-debugger/src/fork/module/network/index.ts @@ -182,13 +182,7 @@ export const networkPlugin = createPlugin('network', ({ devtool, core }) => { headers: headerPipe.getData(), initialPriority: 'High', mixedContentType: 'none', - ...(request.requestData - ? { - postData: contentType?.includes('application/json') - ? JSON.stringify(request.requestData) - : request.requestData - } - : {}) + ...(request.requestData ? { postData: request.requestData.toString() } : {}) }, timestamp: devtool.timestamp, wallTime: request.requestStartTime,