サーバーにCSVファイルがあります。ユーザーがリンクをクリックするとダウンロードされますが、代わりにブラウザウィンドウで開きます。
私のコードは次のようになります
<a href="files/csv/example/example.csv">
Click here to download an example of the "CSV" file
</a>
これは、私がすべての開発作業を行っている通常のWebサーバーです。
私は次のようなものを試しました:
<a href="files/csv/example/csv.php">
Click here to download an example of the "CSV" file
</a>
これで、私のcsv.php
ファイル:
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
現在、私の問題はダウンロード中ですが、CSVファイルではありません。新しいファイルを作成します。
サーバー上のすべてのCSVファイルを強制的にダウンロードするには、.htaccessファイルを追加します。
AddType application/octet-stream csv
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
readfile("/path/to/yourfile.csv");
または、HTML5を使用してこれを行うことができます。単に
<a href="example.csv" download>download not open it</a>
取得を要求されたURLをどう処理するかはブラウザ次第であるため、これを確実に行うことはできません。
Content-dispositionヘッダーを送信することで、すぐに「ディスクに保存」することを提供するブラウザにsuggestを指定できます。
header("Content-disposition: attachment");
これがさまざまなブラウザでどの程度サポートされているかわかりません。別の方法は、アプリケーション/オクテットストリームのコンテンツタイプを送信することですが、それはハックです(基本的には、ブラウザに「これはどんな種類のファイルかは教えません」と伝え、ブラウザはダウンロードダイアログを提供します)、Internet Explorerで問題を引き起こすと言われています。
詳細については Web Authoring FAQ。 をご覧ください。
Editデータを配信するためにPHPファイルに切り替えました-これはContent-ディスポジションヘッダー(これを行うことができるいくつかの不可解なApache設定がない限り)。あとは、そのPHPファイルがCSVファイルの内容を読み取り、それらを印刷するためだけです。ヘッダーのfilename=example.csv
は、ファイルに使用する名前をクライアントブラウザーに提案するだけで、実際にはサーバー上のファイルからデータをフェッチするわけではありません。
より安全なブラウザソリューションを次に示します。
$fp = @fopen($yourfile, 'rb');
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename="yourname.file"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".filesize($yourfile));
}
else
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename="yourname.file"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".filesize($yourfile));
}
fpassthru($fp);
fclose($fp);
メディアタイプapplication/octet-stream
でファイルを送信するようにサーバーを構成します。
きれいな解決策:
<?php
header('Content-Type: application/download');
header('Content-Disposition: attachment; filename="example.csv"');
header("Content-Length: " . filesize("example.csv"));
$fp = fopen("example.csv", "r");
fpassthru($fp);
fclose($fp);
?>
これは、ブラウザがこのファイルタイプを処理できることを意味します。
気に入らない場合、最も簡単な方法はZipファイルを提供することです。誰でもZipファイルを処理でき、デフォルトでダウンロード可能です。
アプリケーション自体でそれをしている場合...このコードが役立つことを願っています。
Hrefで-URLとともにdownload_file.phpを追加する必要があります:
<a class="download" href="'/download_file.php?fileSource='+http://www.google.com/logo_small.png" target="_blank" title="YourTitle">
/* Here is the Download.php file to force download stuff */
<?php
$fullPath = $_GET['fileSource'];
if($fullPath) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-Disposition: attachment; filename=\"" . $path_parts["basename"]."\""); // Use 'attachment' to force a download
header("Content-type: application/pdf"); // Add here more headers for diff. extensions
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");
}
if($fsize) { // Checking if file size exist
header("Content-length: $fsize");
}
readfile($fullPath);
exit;
}
?>
このページの以前の回答では、.htaccessを使用して特定の種類のすべてのファイルを強制的にダウンロードする方法について説明しています。ただし、このソリューションは、すべてのブラウザーのすべてのファイルタイプで機能するわけではありません。これはより信頼性の高い方法です。
<FilesMatch "\.(?i:csv)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
これが正しく機能することを確認するには、ブラウザのキャッシュをフラッシュする必要がある場合があります。
ダウンロードを強制するには、ほとんどのブラウザーでサポートされている_Content-Type: application/force-download
_ヘッダーを使用できます。
_function downloadFile($filePath)
{
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
}
_
より良い方法
この方法でファイルをダウンロードすることは、特に大きなファイルの場合には最適なアイデアではありません。 PHPは、ファイルの内容の読み取りと出力に余分なCPU /メモリを必要とし、大きなファイルを扱う場合、時間/メモリの制限に達する可能性があります。
より良い方法は、PHPを使用してファイルへのアクセスを認証および許可することです。実際のファイルサービスは、X-SENDFILEメソッドを使用してWebサーバーに委任する必要があります(Webサーバーの構成が必要です):
X-SENDFILE
_はLighttpdによってネイティブにサポートされています: https://redmine.lighttpd.net/projects/1/wiki/X-LIGHTTPD-send-filemod_xsendfile
_モジュールが必要です。 https://tn123.org/mod_xsendfile/ Ubuntuでは、_apt install libapache2-mod-xsendfile
_によってインストールできます。X-Accel-Redirect
_ヘッダーがあります: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/_X-SENDFILE
_を処理するようにWebサーバーを設定したら、readfile($filePath)
をheader('X-SENDFILE: ' . $filePath)
に置き換えるだけで、Webサーバーがファイル処理を処理します。これにより、PHP readfile
。
(Nginxの場合、_X-Accel-Redirect
_の代わりに_X-SENDFILE
_ヘッダーを使用します)
注:最終的に空のファイルをダウンロードする場合は、_X-SENDFILE
_ヘッダーを処理するようにWebサーバーを構成しなかったことを意味します。上記のリンクをチェックして、Webサーバーを正しく構成する方法を確認してください。