ケータイFlashのブラウザキャッシュを回避するには

By ookura - 09/06/26 - このエントリをはてなブックマークに追加このエントリをYahoo!ブックマークに追加このエントリをdel.icio.usに追加このエントリをFC2ブックマークに追加

ブラウザキャッシュの問題

動的に生成するケータイFlashの場合、ブラウザキャッシュが残ってしまって困ることがあります。
せっかく動的に生成して内容を更新しているのに一部のユーザーには更新されていないように見えるのです。
 
DoCoMoやSoftbankの端末の場合は再アクセス時は自動的に再読み込みするのですが、
auブラウザのキャッシュが特に強力で、改めてリロードしないとキャッシュが消えない場合があります。
 
 

動的生成の場合

swfのヘッダを出力してバイナリを出力する前に以下のヘッダを出力しておくとブラウザキャッシュを回避することができます。
 

header('Expires: Thu, 01 Jan 1970 00:00:00 GMT, -1');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');

 
以下のような内容を記述した.htaccessファイルを配置しても上記同様の効果があります。
※.htaccessを有効にしておく必要があります。
.htaccess

<Files ~ "\.php$">
    Header set Expires "Thu, 01 Jan 1970 00:00:00 GMT, -1"
    Header set Cache-Control no-cache
    Header set Cache-Control no-store
    Header set Cache-Control must-revalidate
    Header set Pragma no-cache
</Files>

 
 

サンプルFlashファイル概要

sample3935.swf
FlashLite1.1で作成しています。
ステージ中央にダイナミックテキストを配置して「{$time}」と記述しているだけです。
PHPで「{$time}」の部分をサーバー時刻に置き換えます。
 
 

PHPソース例

SWF出力前にヘッダを追加で出力します。
PHPからはサーバー時刻をFlashに組み込む処理を入れています。
sample3935.php

<?php
/* 
 * swfのテキストを置換して出力するサンプル
 */

// ブラウザキャッシュ対策パターンを指定
$nocache = intval($_GET['nocache']);
if (!in_array($nocache, array(0,1))) {
    $nocache = 0;
}

// SWFファイルの内容を取得
$swfData = file_get_contents('sample3935.swf');


// SWFからXMLに変換

// コマンド実行時の入出力とエラー出力先を指定
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "swfmill_error_log", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill -e cp932 swf2xml stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    // 標準入力にSWFファイルのバイナリデータを書き込み
    fwrite($pipes[0], $swfData);
    fclose($pipes[0]);
    
    // 標準出力からXMLデータを読み込み
    $xmlString = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

// 文字列置換

// 置換する値を連想配列で設定
$replaceStrings = array(
    'time'   => date("Y-m-d H:i:s"),
);

foreach($replaceStrings as $key => $value){
    // 文字列内の改行を置換
    $value = str_replace("\n", '&#13;', $value);
    
    // 文字列を連想配列の値に置換
    $xmlString = str_replace('{$' . $key . '}', $value, $xmlString);
    
}


// XMLからSWFに変換

// コマンド実行時の入出力とエラー出力先を指定
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "swfmill_error_log", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill -e cp932 xml2swf stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    
    // 標準入力にXMLデータを書き込み
    fwrite($pipes[0], $xmlString);
    fclose($pipes[0]);
    
    // 標準出力からSWFファイルのバイナリデータを読み込み
    $swfOutput = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

if ($nocache === 1) {
    header('Expires: Thu, 01 Jan 1970 00:00:00 GMT, -1');
    header('Cache-Control: no-cache, no-store, must-revalidate');
    header('Pragma: no-cache');
}

// SWFのヘッダを出力
header('Content-type: application/x-shockwave-flash');

// SWFのデータを出力
echo $swfOutput;

※上記サンプルはUTF-8で記述しています。
※同階層に「swfmill_error_log」を書き換え可能パーミッションで配置する必要があります。
※上記サンプルでのSWFの動的生成にはサーバーへのswfmillのインストールが必要です。
 
ブラウザキャッシュが無効になっていれば戻って再度アクセスすると内容が更新されるはずです。
※ブラウザの進むボタンではなくリンクをクリックします。
 
 

実行例

実行例はこちらからご確認下さい。
Flashにサーバー時刻を動的に埋め込むサンプルです。
キャッシュ対策のヘッダを出力していないものと出力したものの2種類を用意しています。

URLをメールで送る
http://ookura.tanikaze.com/Sample/post3935/
 
 

静的SWFファイルの場合

静的なケータイFlashでもアップロードして更新したのにauユーザーからは更新していないように見える場合があります。
そんな場合は.htaccessで以下のように記述してswfを配置したディレクトリに置きます。
※.htaccessを有効にしておく必要があります。
.htaccess

<Files ~ "\.swf$">
    Header set Expires "Thu, 01 Jan 1970 00:00:00 GMT, -1"
    Header set Cache-Control no-cache
    Header set Cache-Control no-store
    Header set Cache-Control must-revalidate
    Header set Pragma no-cache
</Files>

 
 

参照URL

キャッシュ制御 Others .htaccess
http://w3g.jp/others/htaccess/cache_control
→キャッシュ制御の方法と構文の説明があります。
 
 

備考

※上記ブラウザキャッシュ対策はブラウザを切って再度アクセスした場合や他のページを遷移して再度そのページに戻ってきた場合に有効ですが、
ブラウザの左右や「戻る」「進む」で遷移した場合は効果がない場合があります。
 
※DoCoMoやSoftbankの端末の場合はたいていの機種では、上記キャッシュ対策に関係なく常に最新のファイルを取得して表示します。
 
※機種によっては上記のようなキャリアのキャッシュ表示の傾向と異なる動作をする場合があります。
 
 

関連ページ

ケータイFlash関連の記事一覧