2011-07-12 27 views
29

ボタンがあり、onclickはajax関数を呼び出します。ファイルをajaxコールでダウンロードする

は、ここで私は、ユーザー入力に基づいて、CSVファイルを作成し、私の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); 
} 

です。それが作成された後、私はダウンロードを促したり、ダウンロードを強制したりしたい(できれば強制)。私はファイルをダウンロードするには、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の終わりにそれを実行した場合、それは代わりにダウンロードする(ajaxDivに)ページにfile.csvになりの内容を出力します。

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

答えて

36

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

+16

です。この議論を参照してください:http://stackoverflow.com/questions/7857878/window-location-vs-document-location – yitwail

8

私はこれを隠しiframeで実現しました。私はPHPではなくperlを使用しているので、コードソリューションではなくコンセプトを与えるだけです。

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

クライアント(ジャバスクリプト)は、ファイル名を入力し、ファイルをお届けしますいくつかのURLにiframeのsrcを設定し、のような:

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

Serverは、ファイルをslurpsそれのリンクを解除し、クライアントにストリームを送信し、これらのヘッダーを持つ:

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

魅力的な作品です。

8

@joe:多くのおかげで、これは良い頭でした!私は少し難しい問題だった

:バック サーバーは、ZIPファイル 2を生成するために1が、POSTデータでAJAXリクエストを送信し、応答を取得し 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(); //Append the iFrame to the context this.append(dlif); } else if (data.error) { alert(data.error); } else { alert('Something went 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; 

"要求/ダウンロード" 必要に応じて、いくつかのセキュリティチェックを実行し、ファイル転送を生成することができます:何かのようにjQueryを使用して

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

} 
+0

ちょうど&に必要な変更?クエリ文字列の場合しかし、これで素晴らしい助けをありがとう! - 私は編集をしようとしましたが、それは私をさせないような小さなものでした! $ dlink = 'http://' .$_SERVER ["SERVER_NAME"] '/ request/download?file ='。$ zipid; –

19

を非常にシンプルなソリューション:上の

クライアント側:

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

とサーバ側で、あなたが正しいを返送しますContent-Typeヘッダーがあるため、ブラウザは添付ファイルを認識してダウンロードが開始されます。

+1

+1これは、サーバーへのデータのPOSTと応答としてのZIPファイルのダウンロードのために私にとって素晴らしい仕事でした。ページがリロードされません。 –

+0

+1記事はより技術的であり、良いテクニックです。 – bizzr3

+0

もう少し詳しく説明し、両端で何が起こるかに関するいくつかのコードを提供できますか? –

2

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

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

は、私は技術的にそれは `window.location`を設定する方が良いでしょうと信じていたコード

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

関連するコードを投稿すると、ここで何を言おうとしているのかがわかります。 – larsAnders

+0

あなたのajaxの成功の応答では、あなたは隠しiframeを設定することができますsrc –