はじめに
図のように
1.APIサーバー①でAxiosを利用してAPIサーバー②からExcelファイルを取得
2,APIサーバー①で取得したExcelファイルをサーバー上に保存
する処理を実装したときに、取得したExcelファイルを保存できずに結構ハマったので、備忘録として残しておきます。
(*正しくはエクセルファイルとして保存できるが、ファイルが壊れていて開くことができない)
TL;DR
- Axiosでストリームのレスポンスを受け取る際には、Axiosのoptionsで
responseType: stream
と指定すること- 指定しないと、レスポンスはJSON(デフォルト値)として扱われてしまう
コード(抜粋)
- APIサーバー②のExcelファイルをストリームで返すAPI
app.get(`/api/excel_files`, (req, res) => {
try {
const filePath = 'sample.xlsx';
const fileStream = fs.createReadStream(filePath);
const statusCode = 200
res.status(statusCode);
res.setHeader('Content-Type', 'application/octet-stream');
fileStream.pipe(res);
} catch (error) {
console.log(error);
return res.status(500).send('internal server error');
}
})
- APIサーバー①からAPIサーバー②のAPIを呼び、取得したExcelファイルを保存するコード
const options = {
responseType: 'stream', // !!ポイント!!
}
axios.get(url, options)
.then(response => {
const fileName = `test.xlsx`
response.data.pipe(fs.createWriteStream(fileName));
})
options
に responseType: 'stream'
を指定しないとresponse.data.pipe()
の処理で
response.data.pipe is not a function
と怒られます。
(→response.data
がstreamとして扱われないため、.pipe
で処理できない)
responseTypeについては、Axiosの公式のリクエスト設定に以下のように記載されています。
// `responseType` には、以下のようなサーバーがオプションで応答するデータのタイプを指定します。
// 'arraybuffer'、'document'、'json'、'text'、'stream'
// browser のみ: 'blob'
responseType: 'json', // デフォルト
参考リンク
つぶやき
Axiosにこんなオプションがあるのを知らなかった。
ライブラリのオプションにはどんなものがあるかは使うときに確認するようにしておいたほうがよいという教訓を得た。(知らないよりは知っておいたほうがよい)