I have a server using the Next.js API, whence I want to send the frontend a .csv file encoded in a locale-specific encoding (Shift_JIS).
My server currently uses this approach:
download(res: NextApiResponse, buffer: Buffer, fileName: string) {
res.status(200)
res.setHeader('Content-Type', 'text/csv')
res.setHeader('Content-Disposition', 'attachment; filename="' + fileName + '"')
res.send(buffer)
}
Looking at the logs in the server debugger, it seems that this part is working correctly.
The frontend page uses this code:
try {
const response = await api.getRequestCsv({
// insert necessary parameters here
})
console.log('tried', response)
} catch (e) {
console.log('caught', e)
}
The API object does:
this.request<{
/* @format binary */
file?: File
},
any
>({
path: /safdsfa/download
,
method: 'GET',
query: {code: '123'},
format: 'json',
})
The GET request sent in api.getRequestCsv()
resolves correctly, but when I console.log
it, I get this (abridged for brevity and secrecy):
Response {
data: null
error: "Unexpected token '�', "�v���W�F�N"... is not valid JSON"
body: ReadableStream
locked: true
bodyUsed: true
ok: true
status: 200
statusText: "OK"
type: "basic"
url: // insert intended URL here
}
My suspicion is that the frontend receives the response and, somewhere, it parses the file as a UTF-8 JSON string when it should have downloaded the stream as a file as-is.
How can I force the frontend to download the file in the response as-is instead of assuming that it's a JSON string and parsing it when it shouldn't?
I've figured it out. The server expects to respond with a JSON Object that contains a file, instead of directly responding with a file. I rewrote the backend response to:
download(res: NextApiResponse, buffer: Buffer, fileName: string) {
res.status(200)
res.setHeader('Content-Type', 'text/csv')
res.setHeader('Content-Disposition', 'attachment; filename="' + fileName + '"')
res.send({file: buffer}) // changed
}
and did some complicated things in the frontend to extract the buffer from there and download it locally.