web-dev-qa-db-ja.com

Ajax呼び出しphpを介してファイルをダウンロードする

ボタンがあり、onclickはajax関数を呼び出します。

ここに私のajax関数があります

function csv(){

    ajaxRequest = ajax();//ajax() is function that has all the XML HTTP Requests

    postdata = "data=" + document.getElementById("id").value;

    ajaxRequest.onreadystatechange = function(){
        var ajaxDisplay = document.getElementById('ajaxDiv');
        if(ajaxRequest.readyState == 4 && ajaxRequest.status==200){
            ajaxDisplay.innerHTML = ajaxRequest.responseText;           
        }
    }

    ajaxRequest.open("POST","csv.php",false);
    ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    ajaxRequest.send(postdata);
}

ユーザー入力に基づいてcsvファイルを作成します。作成された後、ダウンロードを促すか、強制的にダウンロードする(できれば強制する)ようにします。 phpファイルの最後にある次のスクリプトを使用して、ファイルをダウンロードしています。このスクリプトを別のファイルで実行すると、正常に機能します。

$fileName = 'file.csv';
$downloadFileName = 'newfile.csv';

if (file_exists($fileName)) {
    header('Content-Description: File Transfer');
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename='.$downloadFileName);
    ob_clean();
    flush();
    readfile($fileName);
    exit;
}
echo "done";

しかし、csv.phpの最後で実行すると、file.csvの内容がダウンロードではなくページ(ajaxDivに)に出力されます。

Csv.phpの最後にファイルを強制的にダウンロードする方法はありますか?

32
theking963

AJAXはファイルをダウンロードするためのものではありません。ダウンロードリンクをアドレスとして新しいウィンドウをポップアップするか、document.location = ...

40
Marc B

JQueryを使用した非常にシンプルなソリューション:

クライアント側:

$('.act_download_statement').click(function(e){
    e.preventDefault();
    form = $('#my_form');
    form.submit();
});

サーバー側では、正しいContent-Typeヘッダー。これにより、ブラウザは添付ファイルを認識し、ダウンロードが開始されます。

20
blink281

@joe:どうもありがとう、これは良いヘッドアップでした!

私は少し難しい問題がありました:1. AJAXリクエストをPOSTデータで送信し、サーバーがZipファイルを生成するために2.応答を取得します3 。Zipファイルをダウンロードする

それが私がそれをやった方法です(AJAXリクエストを処理するためにJQueryを使用):

  1. 最初の投稿リクエスト:

    var parameters = {
         pid     : "mypid",
       "files[]": ["file1.jpg","file2.jpg","file3.jpg"]
    }


    var options = { url: "request/url",//replace with your request url type: "POST",//replace with your request type data: parameters,//see above context: document.body,//replace with your contex success: function(data){ if (data) { if (data.path) { //Create an hidden iframe, with the 'src' attribute set to the created Zip file. var dlif = $('
    <iframe /> '、{' src ':data.path})。hide(); // iFrameをコンテキストに追加します this.append(dlif); } else if(data.error){ alert(data.error); } else { alert( 'Something goes wrong'); } } } }; $。ajax(options);

「request/url」はZipの作成を処理し(トピック外なので、完全なコードを投稿しません)、次のJSONオブジェクトを返します。何かのようなもの:

 //Code to create the Zip file
 //......
 //Id of the file
 $zipid = "myzipfile.Zip"
 //Download Link - it can be prettier
 $dlink = 'http://'.$_SERVER["SERVER_NAME"].'/request/download&file='.$zipid;
 //JSON response to be handled on the client side
 $result = '{"success":1,"path":"'.$dlink.'","error":null}';
 header('Content-type: application/json;');
 echo $result;

「要求/ダウンロード」は、必要に応じていくつかのセキュリティチェックを実行し、ファイル転送を生成できます。

$fn = $_GET['file'];
if ($fn) {
  //Perform security checks
  //.....check user session/role/whatever
  $result = $_SERVER['DOCUMENT_ROOT'].'/path/to/file/'.$fn;
  if (file_exists($result)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/force-download');
    header('Content-Disposition: attachment; filename='.basename($result));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($result));
    ob_clean();
    flush();
    readfile($result);
    @unlink($result);
  }

}
12
Dario

これを非表示のiframeで達成しました。私はphpではなくPerlを使用しているため、コードソリューションではなく概念を説明します。

クライアントはAjax要求をサーバーに送信し、ファイルコンテンツが生成されます。これはサーバーに一時ファイルとして保存され、ファイル名がクライアントに返されます。

クライアント(javascript)はファイル名を受け取り、iframe srcを次のようにファイルを配信するURLに設定します。

$('iframe_dl').src="/app?download=1&filename=" + the_filename

サーバーはファイルを丸lurみし、リンクを解除し、次のヘッダーとともにストリームをクライアントに送信します。

Content-Type:'application/force-download'
Content-Disposition:'attachment; filename=the_filename'

魅力のように機能します。

9
joe

Ajaxから直接ファイルをダウンロードすることはできません。

ファイルへのURL(ajax呼び出しから返される)を使用してページにリンクを配置するか、別の方法として、非表示のiframeを使用し、そのiframeのソースのURLを設定します。動的に。これにより、ページを更新せずにファイルをダウンロードできます。

ここにコードがあります

$.ajax({
    url : "yourURL.php",
    type : "GET",
    success : function(data) {
        $("#iframeID").attr('src', 'downloadFileURL');
    }
});
2