何時間も経った後、
httpsリクエストで画像をダウンロードすることに関する問題を突き止めました。hard path で画像にアクセスすると(https://mysite/tmp/file.jpg)
、apache は正常にそれを返し、余分な操作をしなくてもブラウザーで表示できます。別のパスでアクセスしようとすると
(https://mysite/files/file.jpg)
、php でアクセスを制御するために、php コードから応答が返されますが、ブラウザで画像を表示できません。
- VirtualHost が定義されています。mysite: /var/www/mysite に設定
- $app['controllers']->requireHttps();
環境の説明:
mysite/tmp/file.jpg
mysite/files/.htaccess
//... no files; handled by Silex router. here is the .htaccess:
---
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^ ../web/index.php [L]
</IfModule>
---
- https://mysite/tmp/file.jpg、https:200 で提供され、ブラウザーで表示されます。わかった
- https:// mysite/files/file.jpg は https:200 で提供されますが、ブラウザーでは表示されません。?
試した3つの方法は次のとおりです。
方法 1: Silex sendFile() ダイレクト メソッド >
$app->get('/files/{onefile}', function ($onefile) use ($app) {
// Validate authorization; if ok, then
return $app->sendFile('/var/www/mysite/tmp/' . $onefile);
});
方法 2: Silex ストリーミング >
$app->get('/files/{onefile}', function ($onefile) use ($app) {
// Validate authorization; if ok, then
$stream = function () use ($file) {
readfile($file);
};
return $app->stream($stream, 200, array('Content-Type' => 'image/jpeg'));
方法 3: Symfony2 スタイル >
$app->get('/files/{onefile}', function ($onefile) use ($app) {
// Validate authorization; if ok, then
$exactFile="/var/www/mysite/tmp/" . $onefile;
$response = new StreamedResponse();
$response->setCallback(function () use ($exactFile) {
$fp = fopen($exactFile, 'rb');
fpassthru($fp);
});
$response->headers->set('Content-Type', 'image/jpg');
$response->headers->set('Content-length', filesize($exactFile));
$response->headers->set('Connection', 'Keep-Alive');
$response->headers->set('Accept-Ranges','bytes');
$response->send();
これはChromeが提示するものです:
この Chrome イメージでは、これは Http (Https かどうか、同じ結果) リクエストです。
Request URL:https://mysite/files/tmpphp0XkXn9.jpg
Request Method:GET
Status Code:200 OK
Request Headers:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Cookie:XDEBUG_SESSION=netbeans-xdebug; _MYCOOKIE=u1k1vafhaqik2d4jknko3c94j1
Host:mysite
Pragma:no-cache
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Response Headers:
Accept-Ranges:bytes
Cache-Control:no-cache
Connection:Keep-Alive, Keep-Alive
Content-Length:39497
Content-Type:image/jpg
Date:Thu, 13 Jun 2013 13:44:55 GMT
Keep-Alive:timeout=15, max=99
Server:Apache/2.2.16 (Debian)
X-Powered-By:PHP/5.3.3-7+squeeze15
望ましくない動作の可能性を排除するために行われたその他のテスト:
- BOM をチェックし、リクエストに応答する PHP コードが有効であり、Emacs を使用して望ましくないバイト オーダー マーク (BOM) がないことを確認しました (
set-buffer-file-coding-system utf-8
)。さらに、不明な BOM タグ付きファイルを回避するために、mysite ディレクトリ (grep -rl $'\xEF\xBB\xBF' .
) で次のコマンドを実行しました。異常は見られませんでした。
アップデート:
ブラウザが受信したファイル (画像) (save as
各画像) を見ると、これはツール (Hex Friend) が見つけるのに役立つものですが、その理由はまだわかりません:
2 つのファイルの比較
- (成功したもの: mysite/tmp/file.jpg ; Apache によって直接提供されます)
- (成功しなかったもの: mysite/files/file.jpg; PHP スクリプトによって提供されます)。
バイナリ ファイルの先頭に、次の違いがあります。
バイナリ ファイルの最後に、次の違いがあります。
質問: PHP コードを使用して (ストリームまたはその他の手法で) 画像を返し、ブラウザで表示するにはどうすればよいですか? すべての PHP コード メソッドが同じ出力を返します。環境に問題があると思われます。私が実験しているエラーを生成する可能性のある環境設定はありますか?