質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

6668閲覧

POSTでファイルをJavaScriptで強制ダウンロードさせるには

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2019/08/16 08:51

編集2019/08/16 09:11

やりたいこと

jpgなどブラウザで直接表示されてしまうファイルをJavaScriptでPOSTで強制ダウンロードさせたい。
大きいデータもあるためストリームさせたく、一度blobで受け取り改めて保存させる方式は避けたい。

php

1/* 2POSTで情報受け取り処理 3・・・ 4・・・ 5*/ 6 7$file = './test.jpg'; 8 9header('Content-Type: application/force-download'); 10header('Content-Length: '.filesize($file)); 11header('Content-Disposition: attachment; filename="sample.jpg"'); 12readfile($file);

POSTの理由

  • リクエスト内容に応じてDL対象ファイルを動的にするため
  • 単純な直リン(URLシェア等)を簡単に防ぎたいため

試したこと

HTMLのFORMやハイパーリンク(GET)であれば、期待通りダウンロードが始まりました。
JavaScriptで非同期通信をした場合はバイナリデータをそのまま受け取ってしまいダウンロードが始まりませんでした。
→ Content-Type: application/force-downloadヘッダが無視される

JavaScript

1let data = new FormData; 2 3data.append('test1', 'hoge1'); 4data.append('test2', 'hoge2'); 5 6axios.post('/download', data) 7 .then((response) => { 8 //何も起こらない(レスポンス内容は対象のバイナリデータ) 9 }) 10 .catch((error) => { 11 console.log(error); 12 })

非同期で該当ヘッダが無視される原因はブラウザのセキュリティでしょうか?
(特にコンソールにエラー類は出ていない)
もしくは手法が違えばご教示お願いいたします。

最終手段としてjsでformを生成してsubmitさせれば実現できるとは思いますが、
あまりスマートではない気がしまして質問させていただきました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Content-Type: application/force-download

そもそもこれは存在しません。→定義一覧
ブラウザにとっては未知のContent-Typeなので、ファイルとして保存しかやりようがないだけです。(しかもそれもブラウザ依存)

また、JavaScriptで非同期通信をした場合、それを受け取るのもJavaScript側なので、Blobにしない限りファイルとして受け取れません。

できることの一例として、以下が考えられます。

  • POSTのAPIをJSから叩き、キーを受け取る。
  • そのキーをGETのAPIに投げて、ファイルを受け取る。
    ※このAPIは、例えばJavaScriptからaタグを生成→クリック→削除みたいな手を使って、HTML側から触らせる

この場合、サーバー側では、POSTを叩かれたらキーを発行し、何度もアクセスされないように、キーの有効期限(例えば発行から5分)をつける、キーとファイルの結びつけをする(ファイルが複数あるなら)のように、サーバー側でも実装は必要です。

サーバーの実装が面倒であれば、JSでformを作ってSubmit後削除するのが一番楽だと思います。

投稿2019/08/17 01:00

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/08/21 21:45

存在しないヘッダだったのですね。 慣習的な名称だったとは勉強になりました。 また、POSTでキーを受け取るご提案も採用させていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問