Getやpostなどの基本的なhttpリクエストにaxiosを使用していますが、うまく機能します。次に、Excelファイルもダウンロードできるようにする必要があります。これはaxiosで可能ですか?もしそうなら、誰かがいくつかのサンプルコードを持っていますか?そうでない場合、反応アプリケーションで同じことをするために他に何を使用できますか?
応答にダウンロード可能なファイルが付属している場合、応答ヘッダーは次のようになります
Content-Disposition: "attachment;filename=report.xls"
Content-Type: "application/octet-stream" // or Content-type: "application/vnd.ms-Excel"
できることは、非表示のiframeを含む別のコンポーネントを作成することです。
import * as React from 'react';
var MyIframe = React.createClass({
render: function() {
return (
<div style={{display: 'none'}}>
<iframe src={this.props.iframeSrc} />
</div>
);
}
});
これで、ダウンロード可能なファイルのURLをこのコンポーネントにpropとして渡すことができます。したがって、このコンポーネントがpropを受け取ると、再レンダリングされ、ファイルがダウンロードされます。
Edit:js-file-download モジュールも使用できます。 Githubリポジトリへのリンク
const FileDownload = require('js-file-download');
Axios.get(`http://localhost/downloadFile`)
.then((response) => {
FileDownload(response.data, 'report.csv');
});
お役に立てれば :)
Axiosと何らかのセキュリティ手段を使用してファイルをダウンロードする場合、これは実際にはさらに複雑です。他の誰かがこれを理解するのにあまりにも多くの時間を費やすことを防ぐために、私はこれを通してあなたを歩かせます。
次の3つのことを行う必要があります。
1. Configure your server to permit the browser to see required HTTP headers
2. Implement the server-side service, and making it advertise the correct file type for the downloaded file.
3. Implementing an Axios handler to trigger a FileDownload dialog within the browser
これらの手順はほとんど実行可能ですが、ブラウザとCORSの関係によりかなり複雑です。一歩ずつ:
トランスポートセキュリティを採用する場合、ブラウザ内で実行されるJavaScriptは、[設計により] HTTPサーバーから実際に送信された6つのHTTPヘッダーのみにアクセスできます。サーバーがダウンロード用のファイル名を提案したい場合、ブラウザに、提案されたファイル名が転送される他のヘッダーへのアクセスをJavaScriptに許可することを「OK」にする必要があります。
議論のために、サーバーがX-Suggested-Filenameと呼ばれるHTTPヘッダー内の推奨ファイル名を送信することを想定します。 HTTPサーバーはブラウザに、OKであることを伝え、この受信したカスタムヘッダーを次のヘッダーでJavaScript/Axiosに公開します。
Access-Control-Expose-Headers: X-Suggested-Filename
HTTPサーバーを構成してこのヘッダーを設定する正確な方法は、製品ごとに異なります。
これらの標準ヘッダーの詳細な説明と詳細な説明については、 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers を参照してください。
サーバー側のサービス実装では、次の2つのことを実行する必要があります。
1. Create the (binary) document and assign correct ContentType to the response
2. Assign the custom header (X-Suggested-Filename) containing the suggested file name for the client
これは、選択したテクノロジースタックに応じてさまざまな方法で実行されます。 Excelレポートを出力するJavaEE 7標準を使用した例をスケッチします。
@GET
@Path("/report/Excel")
@Produces("application/vnd.ms-Excel")
public Response getAllergyAndPreferencesReport() {
// Create the document which should be downloaded
final byte[] theDocumentData = ....
// Define a suggested filename
final String filename = ...
// Create the JAXRS response
// Don't forget to include the filename in 2 HTTP headers:
//
// a) The standard 'Content-Disposition' one, and
// b) The custom 'X-Suggested-Filename'
//
final Response.ResponseBuilder builder = Response.ok(
theDocumentData, "application/vnd.ms-Excel")
.header("X-Suggested-Filename", fileName);
builder.header("Content-Disposition", "attachment; filename=" + fileName);
// All Done.
return builder.build();
}
サービスはバイナリドキュメント(この場合はExcelレポート)を発行し、正しいコンテンツタイプを設定します。また、ドキュメントの保存時に使用する推奨ファイル名を含むカスタムHTTPヘッダーを送信します。
ここにはいくつかの落とし穴がありますので、すべての詳細が正しく構成されていることを確認しましょう。
スケルトンAxios実装は、次のようなものになります。
// Fetch the dynamically generated Excel document from the server.
axios.get(resource, {responseType: 'blob'}).then((response) => {
// Log somewhat to show that the browser actually exposes the custom HTTP header
const fileNameHeader = "x-suggested-filename";
const suggestedFileName = response.headers[fileNameHeader];'
const effectiveFileName = (suggestedFileName === undefined
? "allergierOchPreferenser.xls"
: suggestedFileName);
console.log("Received header [" + fileNameHeader + "]: " + suggestedFileName
+ ", effective fileName: " + effectiveFileName);
// Let the user save the file.
FileSaver.saveAs(response.data, effectiveFileName);
}).catch((response) => {
console.error("Could not Download the Excel report from the backend.", response);
});
より一般的なソリューション
axios({
url: 'http://api.dev/file-download', //your url
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf'); //or any other extension
document.body.appendChild(link);
link.click();
});
https://Gist.github.com/javilobo8/097c30a233786be52070986d8cdb174 で癖をチェックしてください
完全なクレジット: https://Gist.github.com/javilobo8
axios.get(
'/app/export'
).then(response => {
const url = window.URL.createObjectURL(new Blob([response]));
const link = document.createElement('a');
link.href = url;
const fileName = `${+ new Date()}.csv`// whatever your file name .
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
link.remove();// you need to remove that elelment which is created before.
})
ユーザーのダウンロードをトリガーするのは非常に簡単なJavaScriptコードです。
window.open("<insert URL here>")
この操作にaxiosが必要/不要です。ブラウザにそれをさせるのが標準です。
注:ダウンロードの承認が必要な場合、これは機能しない可能性があります。同じドメイン内にある限り、Cookieを使用してこのようなリクエストを承認できると確信していますが、それでもこのような場合はすぐに動作しない可能性があります。
possible...かどうかについて 組み込みのファイルダウンロードメカニズムではなく、no 。
IEおよび他のブラウザを使用したAxios.postソリューション
ここで素晴らしいソリューションを見つけました。しかし、彼らはIEブラウザーの問題をしばしば考慮しません。たぶん、それは他の誰かにいくらかの時間を節約するでしょう。
axios.post("/yourUrl"
, data,
{responseType: 'blob'}
).then(function (response) {
let fileName = response.headers["content-disposition"].split("filename=")[1];
if (window.navigator && window.navigator.msSaveOrOpenBlob) { // IE variant
window.navigator.msSaveOrOpenBlob(new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}),
fileName);
} else {
const url = window.URL.createObjectURL(new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', response.headers["content-disposition"].split("filename=")[1]);
document.body.appendChild(link);
link.click();
}
}
);
上記のExcelファイルの例ですが、ほとんど変更することなく、任意の形式に適用できます。
そして、サーバー上でExcelを送信するためにこれを行いました
response.contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=exceptions.xlsx")
秘Theは、render()
に不可視のアンカータグを作成し、React ref
を追加して、axios応答が得られたらクリックをトリガーできるようにすることです。
class Example extends Component {
state = {
ref: React.createRef()
}
exportCSV = () => {
axios.get(
'/app/export'
).then(response => {
let blob = new Blob([response.data], {type: 'application/octet-stream'})
let ref = this.state.ref
ref.current.href = URL.createObjectURL(blob)
ref.current.download = 'data.csv'
ref.current.click()
})
}
render(){
return(
<div>
<a style={{display: 'none'}} href='empty' ref={this.state.ref}>ref</a>
<button onClick={this.exportCSV}>Export CSV</button>
</div>
)
}
}
ドキュメントは次のとおりです。 https://reactjs.org/docs/refs-and-the-dom.html 。同様のアイデアをここで見つけることができます: https://thewebtier.com/snippets/download-files-with-axios/ 。
AxiosでAPI呼び出しを行う関数:
function getFileToDownload (apiUrl) {
return axios.get(apiUrl, {
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/json'
}
})
}
関数を呼び出して、取得したExcelファイルをダウンロードします。
getFileToDownload('putApiUrlHere')
.then (response => {
const type = response.headers['content-type']
const blob = new Blob([response.data], { type: type, encoding: 'UTF-8' })
const link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'file.xlsx'
link.click()
})