d3.js を使用して SVG としてオンザフライでグラフを作成しています。これらのグラフは、認証されたユーザーの選択に基づいて動的に生成されます。これらのチャートが生成されると、ユーザーは生成された SVG を PNG または PDF としてダウンロードすることができます。
現在のワークフローは次のとおりです。
// JAVASC
// get the element containing generated SVG
var svg = document.getElementById("chart-container");
// Extract the data as SVG text string
var svg_xml = (new XMLSerializer).serializeToString(svg);
// Submit the <FORM> to the server.
var form = document.getElementById("svgform");
form['output_format'].value = output_format; // can be either "pdf" or "png"
form['data'].value = svg_xml ;
form.submit();
FORM 要素は非表示のフォームで、データを POST するために使用されます。
<form id="svgform" method="post" action="conversion.php">
<input type="hidden" id="output_format" name="output_format" value="">
<input type="hidden" id="data" name="data" value="">
</form>
PHP ファイルは、提供された SVG データを一時ファイルとして保存します。
// check for valid session, etc - omitted for brevity
$xmldat = $_POST['data']; // serialized XML representing the SVG element
if(simplexml_load_string($xmldat)===FALSE) { die; } // reject invalid XML
$fileformat = $_POST['output_format']; // chosen format for output; PNG or PDF
if ($fileformat != "pdf" && $fileformat != "png" ){ die; } // limited options for format
$fileformat = escapeshellarg($fileformat); // escape shell arguments that might have snuck in
// generate temporary file names with tempnam() - omitted for brevity
$handle = fopen($infile, "w");
fwrite($handle, $xmldat);
fclose($handle);
一時ファイル ($infile) を読み取り、指定された $fileformat (PDF または PNG) で新しいファイル ($outfile) を作成する変換ユーティリティが実行されます。結果の新しいファイルがブラウザーに返され、一時ファイルが削除されます。
// headers etc generated - omitted for brevity
readfile($outfile);
unlink($infile); // delete temporary infile
unlink($outfile); // delete temporary outfile
JavaScript (canvg()、次に toDataURL、次に document.write) を使用して SVG を PNG に変換することを調査しましたが、これを使用して PNG を生成できますが、PDF への変換はできません。
そう: ファイルに書き込まれる前に、conversion.php に提供される SVG データを最適にサニタイズまたはフィルタリングするにはどうすればよいでしょうか? SVG サニタイズの現状は? PHP 内で利用できるものは何ですか? conversion.php に提供された SVG データをサニタイズするため のホワイトリスト ベースのアプローチを使用する必要がありますか、それともより良い方法がありますか?
(XSLT はわかりませんが、勉強してみることはできます。できるだけ PHP 内でサニタイズを維持したいと考えています。Windows Server 2008 を使用しているため、外部ツールを使用するソリューションはすべて、そのエコシステム内で利用できる必要があります。)