2011年1月21日金曜日

IEでのダウンロード処理 問題と対策

ファイルをダウンロードさせる処理で、IE7で問題がでてたので、なんとなくメモ。

[問題]
a) https通信のページで、IEだけファイルのダウンロードできない。。(IE8は不明)
b) ファイル名に日本語を含めると文字化け
c) mp3ファイルをダウンロードさせると、必ずメディアプレイヤーが起動されてしまう。

とりあえず今回は、「a) https通信のページで、IEだけファイルのダウンロードできない。」だけメモ。

調べてみると、IEの仕様のようで、Microsoftのサポートページにちと古いけど掲載されていた。

(Content-Disposition: attachemnt と Cache-Control: no-cache によるダウンロードの問題)
http://support.microsoft.com/default.aspx?scid=kb;ja;436605

(Internet Explorer が SSL 経由によるファイルのダウンロードで "No-Cache" ヘッダーを処理できない)
http://support.microsoft.com/kb/323308/ja
(Internet Explorer で SSL Web サイトの Office 文書を開けない)
http://support.microsoft.com/kb/316431/ja


上記ページでは、対象製品はIE5やIE6SP1などになっていましたが、IE7になってもブラウザ側で対処してくれてはいないようです。
#他のブラウザでは出ないんだから、がんばってほしかった。orz

現象は、HTTPヘッダーに、以下のようにキャッシュしないように指定している場合に発生するそうです。

Pragma:no-cache
Cache-control:no-chache,max-age=0,must-revalidate


解決方法のひとつとして、レジストリを使用して回避する方法が書いてあったけど、そんなことを使う人にお願いできるような環境に無いので、他の方法を調査。

解決策としては、HTTPヘッダーに

Pragma:private
Cache-control:private

を出力すればよさそう。

PHPの場合だと、header()関数を使って、
header("Cache-Control:private");
header("Pragma:private");

とかけばよいそうです。


サーバ側でZend Frameworkを使っているので、Zend_http_ResponseクラスのsetHeader()を使ってやればOKなはずということで、ControllerクラスのxxxAction()の中で、

$response=$this->getRequest();
$response->clearHeaders();
$response>setHeader(" Cache-Control ","private");
$response>setHeader(" Pragma ","private");

として、データを出力する前にヘッダーを操作してたんだけど、なぜか、症状がかわらない。

ヘッダーの内容を確認していると、

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, must-revalidate, post-check=0,pre-check=0,private
Pragma: no-cache, private


となっていて、なにも操作していないのに、すでにno-cacheが設定済みになっている。
直前にclearHeader()メソッドを実行しているんだから、消してくれるのだと思ったけど、そうでもないみたい。
どうしたものかと、リファレンスを読んでみると、setHeader()には3番目の引数があって、同じ項目に対して上書きするか制御ができることがわかった(デフォルトはfalse)。

なので、

$response>setHeader(" Cache-Control ","private",true);
$response>setHeader(" Pragma ","private",true);


として、3番目の引数にtrueを設定することで、回避できた。
※なぜno-cacheが設定されいるかは今でもわかんない。暇ができたら調べてみよう。

2011年1月11日火曜日

jQuery Mobile その5(リスト)

リストをきれいに表示してくれる機能があるので、なんとなくメモ。

ulタグや、olタグにdata-role="listview" をつけることで、デラックスなリストを表示してくれる。

(記載例)
  <ul data-role="listview">
<li>リスト1番目</li>
<li>リスト2番目</li>
</ul>
さらに、data-inset="true" をつけると、角丸なリストを表示してくれる。
(記載例)
  <ul data-role="listview" data-inset="true">
      <li>リスト1番目</li>
<li>リスト2番目</li>
</ul>

liタグ内の内容をaタグで括ると、自動的に右方向アイコンが表示される。
(記載例)
<ul data-role="listview" data-inset="true">
<li><a href="aa.html" rel="external">リスト1番目</a></li>
<li>リスト2番目</li>
</ul>
リストの中でliタグにdata-role="list-divider"の属性をつけると、通常のリスト表示とは異なり、サブタイトルのように表示される。
(記載例)
<ul data-role="listview" data-inset="true">
    <li data-role="list-divider">リストタイトル</li>
<li><a href="aa.html" rel="external">リスト1番目</a></li>
</ul>

liタグの子要素としてブロック要素が存在する場合、ブロック要素にCSSクラスとして、ui-li-asideクラスを設定すると、右側に寄せて表示してくれる。
(記載例)
<ul data-role="listview" data-inset="true">
    <li><h3>タイトル</h3><p>内容</p><p class="ul-li-aside">注釈</p></li>
</ul>

画像付のリストも表示することができる。
画像を表示したければ、liタグの中で、imgタグを使って画像を表示すればよい。
ただし、自動的に縦、横どちらかが80px(標準?) or 40px(iconモード?)に縮小した形で表示される。
imgタグにCSSクラスとして、ui-li-iconクラスを設定すると、iconモード(?)で表示される。

(記載例)
<ul data-role="listview" data-inset="true">
<li><img src="images/xxx.jpg"/>
<h1>大きい画像サンプル</h1>
</li>
<li><img src="images/xxx.jpg" class="ui-li-icon"/>
<h1>小さい画像サンプル</h1>
</li>
</ul>




2011年1月7日金曜日

jQuery Mobile その4(テーマ)

jQueryは、UI部品のデザインというか配色を手軽に変更できる機能があるので、とりあえずメモ。

指定できるテーマは5種類で、a,b,c,d,eをdata-theme属性の属性値として指定する。

(指定パターン)
a:黒系
b:ブルー系
c:ライトグレー(?)
d:ダークグレー(?)
e:イエロー

(指定例)

<a data-role="button" data-theme="e">ボタン</a>


テーマはボタン部位以外にも、ほとんどすべてのUI(できないのがあるのか?調べてない)で変更が可能。
入れ子になるような場合でも、別々に指定が可能で、子要素にあたるところでテーマを指定していない場合は、上位のテーマが継承される。

2011年1月6日木曜日

jQuery Mobile その3(ボタン)

jQuery Mobileには、aタグや、form要素を角丸のボタンのように表示してくる機能があるので、とりあえずメモ。

aタグにdata-role="button" と属性を追加すると、ボタンに表示してくれる。
(記載例)

<a data-role="button">ボタン</a>



他に何も属性をつけないと、横方向に画面いっぱいの表示を行う。
data-inline="true"を追加すると、キャップション分の幅で表示してくれる。

ボタンにアイコンをつけることも可能で、その場合は、data-icon="xxxx"と指定する。
指定できるのは、標準で16パターン(自分でCSSを定義すれば拡張は可能なようです)。

(指定可能なパターン)
delete
check
gear
minus
plus
arrow-l
arrow-r
arrow-d
arrow-u
refresh
forward
back
grid
star
alert

デフォルトでは、ボタンの左側に表示されるけど、data-i-conpos="xxx"で表示する場所や見せ方を指定できる。
(指定パターン)
 right:テキストの右側
 top:テキストの上
 bottom:テキストの下
 notext:テキストなしでアイコンのみ

フォームタグは自動的にボタンの表示にされるようです。
(対象タグ)
button,submit,reset,image


ボタンを複数並べる際に、グループ化して、きれいに並べることもできます。
その場合は複数のaタグなどをdivタグで括り、data-role="controlgroup"を属性として記載します。


(記載例)

<div data-role="controlgroup">
<a data-role="button">ボタン1</a>
<a data-role="button">ボタン2</a>
</div>


何もしないと垂直方向に並べますが(リストっぽい)、data-type="horizontal" を追加すると、水平方向へ並べて表示してくれます。

2011年1月4日火曜日

jQuery Mobile その2(リンクのさせ方)

jQuery MobileでのリンクのデフォルトはAjaxで処理をするようになっている。

1)ページ内リンク
リンク先にID指定すると、ページ内にdata-role="page"で定義されているコンテンツに切り替えて表示をしてくれる。

指定例)
 <a href="#hoge">リンク</a>

2)ページ外リンク(Ajax)

リンク先に外部コンテンツを指定すると、表示をアニメーション付で切り替えて表示をしてくれる。
ただし、Ajaxで読みこむため、URLが
   http://ドメイン/呼びもと.html#hoge.html
となり、少し使いづらい。ベースとなるURLが呼びもとのHTMLとなるため、画像のリンク切れとか。

指定例)
<a href="hoge.html">リンク</a>

3)ページ外リンク(Non Ajax)
Ajax抜きで通常のリンク処理のように画面全体をリフレッシュしたい場合は、
「rel="external"」 をタグの属性として指定する。
指定例)
<a rel="external" href="hoge.html">リンク</a>



jQuery Mobile その1

jQuery Mobileを仕事で利用することになりそうなので、とりあえずメモ。

jQuery MobileはjQueryに追加するモバイル向けのUI集。このため、jQueryは必須。

iOS,Android,Symbian,BlackBerryOSなど多くのプラットフォームをサポートしている。

ダウンロードはこちらから。

基本的なページ構成は以下の通り。

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf8">
<!-- jQuery Mobile用CSS読み込み -->
<link rel="stylesheet" href="js/jquery.mobile-1.0a2.min.css" />
<!-- jQuery 本体読み込み -->
<script src="js/jquery-1.4.4.min.js"></script>
<!-- jQuery Mobile読み込み -->
<script src="js/jquery.mobile-1.0a2.min.js"></script>
</head>
<body>
<!-- ページヘッダー部 -->
<div data-role="page" id="home">
<div data-role="header">
<h1>Page Title</h1>
</div>
<!-- ページコンテンツ部-->
<div data-role="content">
<p>Hello, world !</p>
</div>
<!-- ページフッター部 -->
<div data-role="footer">
<p>フッター</p>
</div>
</div>
</body>
</html>

2011年1月3日月曜日

Zend Framework ファイルアップロード処理

Zend FrameworkのZend_Controller_Request では、ファイルアップロードに関する操作が行え無い(ような)ので、$_FILESと@move_upload_file()を利用する。

アップロードされるファイルの情報は、

$_FILES['パラメータ名']['xxxx']
でアクセスする。
複数のファイルをアップロードする場合は、パラメータ名をそれぞれ対応するもので置き換える。

詳細情報(xxxx)は、以下で取得する。

1)ファイル名(name)
2)ファイルサイズ(size)
3)テンポラリファイル名(tmp_name)
4) MIMEタイプ(type)
5)エラーコード(error)
  正常終了の場合:UPLOAD_ERR_OK(0)
  ファイルが設定されていない場合:UPLOAD_ERR_NO_FILE (4)
 
move_uploaded_file関数で、テンポラリファイルを他のディレクトリへコピーする。
テンポラリファイルは、PHPのスクリプトが終了すると削除される。

move_uploaded_file($_FILES['パラメータ名']['tmp_name'], ファイル名パス);

※ファイル名パスは、相対パスでもOK

コード例)
if($_FILES['パラメータ名']['error'] == UPLOAD_ERROR_OK){
   move_uploaded_file($_FILES['パラメータ名']['tmp_name'], ファイル名フルパス);
}