2020.01.31TweetPDFの閲覧だけを許可して、印刷やダウンロードはさせたくないという要望があった場合の対応方法です。URLを指定すればブラウザで簡単にPDFを表示できますが、この状態でPDFの印刷やダウンロードを制御するのはむずかしいので、「PDF.js」というjavaScriptで書かれたライブラリを使って目的に対応します。■PDF.jsの簡単な使い方PDF.jsのビュワーでPDFを表示させるのはとても簡単です。下記から「Stable(安定版)」をダウンロードしてください。ここではバージョン「2.2.228」をダウンロードしたことにします。https://mozilla.github.io/pdf.js/getting_started/#download展開したものをサーバに設置します(ここでは「http://localhost/」にアップしたとして表記し、リンクは「http://chaordic.co.jp/memorandum/article/」にアップされたものが表示されます」)。ローカル・サーバ環境のルートにバージョン「2.2.228」を設置した場合、下記であらかじめ用意されているサンプルPDF(compressed.tracemonkey-pldi-09.pdf)を表示することができます。http://localhost/pdfjs-2.2.228-dist/web/viewer.html指定のPDFを表示させたい場合は、「viewer.html」の後に「?file=PDFのファイル名」と指定することで表示できます。ここには、「相対パス」「絶対パス」「URL」を指定することができます。http://localhost/pdfjs-2.2.228-dist/web/viewer.html?file=compressed.tracemonkey-pldi-09.pdfここでは、これ以上PDF.jsについての詳しい説明はしません。PDF.jsは、とてもすぐれたライブラリで、PDFビュワーであるばかりでなく、PDFレンダーでもあります。実はブラウザに搭載されてるPDFビューアにも、このPDF.jsが使われていたりします。PDFレンダーでいちからPDFビューワを自作するような方法をとれば、もっと完全に目的に対応できるのかもしれませんが、かなりの労力が必要になりそうなので、ここではあらかじめ用意されているPDFビューワを改造して目的に対応します。■印刷できないようにCSSで指定するそれでは、CSSとjavaScriptとjQueryとPHPのファイルを追加して、PDF.jsで印刷やダウンロードができないようにしていきます。「.../pdfjs-2.2.228-dist/web/」の配下にある「viewer.html」をコピーして「viewer_custom.html」とリネームします。次に同じディレクトリに「_custom.css」を作って以下を記述します。none;}}これは単純にCSSのメディアクエリによる指定ですね。これによって印刷時にはbody配下のすべてが空白になります。■印刷やダウンロードのボタンを消す印刷のボタンが不要になりますので、続けてCSSでボタンを消します。「_custom.css」に追記します。!important;}これで、このファイルを「viewer_custom.html」に読み込ませると印刷とダウンロードのボタンを消すことができます。「viewer.css」を読み込んでいる箇所の下あたりがいいと思います。同時にファイルオープンやブックマークのボタンも消してしまいたい場合は、以下のようにします。!important;}■PDFのパスを隠蔽するここまでで、とりあえずPDF.jsのUIによる印刷やダウンロードができなくなりました。右クリックで「印刷」を選択して印刷プレビューを表示させてみても、そこには空白が表示されていると思います。「名前をつけて保存」してみても、そのファイルでPDFは再現されないでしょう。一般のユーザを対象にしたものならば、ここまでで十分だと思いますが、ビュワーを起動するのに「?file=pdf-1.pdf」のように「PDFのパス」が晒されてしまっています。これを見れば、元のPDFファイルがどこにあるのか一目瞭然で、そこにアクセスされてしまえば印刷もダウンロードも容易にできてしまいます。この「PDFのパス」をJavaScriptとPHPをつかってなんとか隠してみます。「pdfjs-2.2.228-dist/」の直下に「_hide/」というディレクリをつくって、そこに「no*.pdf」というファイル名のPDFを3つ入れておきます。このPDFをパスを隠蔽して表示させます。これから追加するファイルを含め下記に示します。_custom.php「web/」の配下に以下の内容の「_custom.js」を用意します。エラー処理など}).fail(function(data){console.error(data);});}});同じディレクトリに「_custom.php」を以下の内容で用意します。$pdf;}exit();?>それから「viewer_custom.html」に上記のJSとCSS、またjQueryを読み込むように追記します。先に追記した「_custom.css」を読み込んでいる箇所の下あたりがいいと思います。ここまで準備できましたら、「viewer_custom.html」に「?file=_custom.php&no=1」のようにパラメータを付与してアクセスしてみてください。http://localhost/pdfjs-2.2.228-dist/web/viewer_custom.html?file=_custom.php&no=1http://localhost/pdfjs-2.2.228-dist/web/viewer_custom.html?file=_custom.php&no=2http://localhost/pdfjs-2.2.228-dist/web/viewer_custom.html?file=_custom.php&no=3これで、URLのパラメータから、表示するPDFのパスを類推するのが難しくなりました。■仕組み仕組みとしては、まずURLパラメータに付加された「no」の値を「_custom.js」で取得し、ajaxで「_custom.php」に送り、それをPHPのセッションに格納します。この後、指定されたパラメータ「_custom.php&no=1」をPDF.jsはPDFだと思って取りにいくわけですが、パスとして評価されるのは「_custom.php」だけです。ひとつのPDFを出力するのに、二度「_custom.php」が叩かれるというわけです。二度目の「_custom.php」へのアクセスは、センションに格納されたnoを頼りに、指定されたPDFを読み込んで出力します。このような、あまりスマートな方法とはいえない方法ですが、そんなことをしています。これで一通り動作を確認できますが、実際につかうとなると、セキュリティの配慮や、エラー処理など、様々な追加が必要になると思います。実装できそうにない場合は弊社にご相談ください。ブラウザのデベロッパー・ツールをつかってCSSを編集すれば、PDF.jsのボタンを復活させることは可能なので、あくまで完全ではない、一般ユーザを対象とした対策とお考えください。indexソースコードは自己責任により自由にお使いください。何らかの不利益が生じたとしても一切責任を負いません。