web-dev-qa-db-ja.com

axiosを使用してファイルをダウンロードする方法

Getやpostなどの基本的なhttpリクエストにaxiosを使用していますが、うまく機能します。次に、Excelファイルもダウンロードできるようにする必要があります。これはaxiosで可能ですか?もしそうなら、誰かがいくつかのサンプルコードを持っていますか?そうでない場合、反応アプリケーションで同じことをするために他に何を使用できますか?

33
David Choi

応答にダウンロード可能なファイルが付属している場合、応答ヘッダーは次のようになります

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');
   });

お役に立てれば :)

48
Hardik Modha

ファイルのダウンロード(Axiosとセキュリティを使用)

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の関係によりかなり複雑です。一歩ずつ:

1.(HTTP)サーバーを構成する

トランスポートセキュリティを採用する場合、ブラウザ内で実行される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.サーバー側のサービスを実装する

サーバー側のサービス実装では、次の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ヘッダーを送信します。

3.受信したドキュメントのAxiosハンドラーを実装する

ここにはいくつかの落とし穴がありますので、すべての詳細が正しく構成されていることを確認しましょう。

  1. サービスは@GET(つまり、HTTP GET)に応答するため、axios呼び出しは「axios.get(...)」でなければなりません。
  2. ドキュメントはバイトストリームとして送信されるため、応答をHTML5 Blobとして扱うようにaxiosに指示する必要があります。 (つまり、responseType: 'blob')。
  3. この場合、ブラウザのダイアログを開くために、ファイルセーバーJavaScriptライブラリが使用されます。ただし、別のものを選択することもできます。

スケルトン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);
    });
31

より一般的なソリューション

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

26
Viney
        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.
})
1
Nitin Tyagi

ユーザーのダウンロードをトリガーするのは非常に簡単なJavaScriptコードです。

window.open("<insert URL here>")

この操作にaxiosが必要/不要です。ブラウザにそれをさせるのが標準です。

注:ダウンロードの承認が必要な場合、これは機能しない可能性があります。同じドメイン内にある限り、Cookieを使用してこのようなリクエストを承認できると確信していますが、それでもこのような場合はすぐに動作しない可能性があります。


possible...かどうかについて 組み込みのファイルダウンロードメカニズムではなく、no

1
Multihunter

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")
0
Alex

秘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/

0
enjolrasyn

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()
  })
0
roli roli