Я пытаюсь передать большой CSV-файл в ответе express, размещенном на heroku. Я так понимаю, что по истечению тайм-аутов через 30 секунд данные не отправляются. Но я также читал, что heroku увеличивает время ожидания на 55 se c каждый раз, когда отправляется кусок данных. Я думал, что использование потокового ответа вызовет этот тайм-аут, но я продолжаю получать тайм-ауты.
Это маршрут express:
const queryStream = await Sale.aggregate([
// a large query
])
.cursor()
.exec()
const csvTransform ... // a csv transform function
queryStream.on('error', error => {
throw error
})
queryStream.on('end', () => res.end())
// queryStream.on('data', row => console.log('### row was processed', row))
res.set(
'Content-Disposition',
'attachment; filename=sales-export-server.csv',
)
res.set('Content-Type', 'text/csv; charset=UTF-8')
res.set('Access-Control-Expose-Headers', 'Content-Disposition')
queryStream.pipe(csvTransform).pipe(res)
и выборка на стороне клиента:
export const streamFetch = async (endpoint, method = 'GET', body) => {
logFetchCalls(endpoint, method, body)
try {
const headers = {
'Content-Type': 'application/json',
// 'Transfer-Encoding': 'chunked',
Authorization: `Bearer ${TOKEN}`,
}
const response = await fetch(`${apiEnv.api}/${endpoint}`, {
method,
headers,
})
const contentType = response.headers.get('content-type')
if (contentType && contentType.indexOf('text/csv') !== -1) {
const filename = response.headers
.get('content-disposition')
.split('filename=')[1]
const data = await response.text()
download(data, filename)
return data
}
return response
} catch (err) {
console.error(err)
throw err
}
}
Когда я использую небольшой набор данных, CSV загружается правильно и быстро (на героку).
Когда я тестирую его локально (без героку / тайм-ауты) с самым большим набором данных, это занимает 38 секунд, но потом я получаю правильный CSV-файл.