maxlength属性の仕様の違いには要注意!

入力フォームではおなじみのmaxlength属性。携帯ブラウザでも使えるけど、やっぱり機種依存がある。機種依存の影響は大きく、場合によっては画面遷移やDB定義にまで手をつけないといけないことも・・・。

まずは手元にある端末を使って実機調査を敢行した。

maxlength属性は最大バイト数?それとも最大文字数?

そもそも maxlength属性ってバイト数で指定するのか、それとも文字数で指定するのか?まずはHTMLの仕様書で確認してみる。

17.4 The INPUT element

maxlength = number [CN]

When the type attribute has the value “text” or “password”, this attribute specifies the maximum number of characters the user may enter. This number may exceed the specified size, in which case the user agent should offer a scrolling mechanism. The default value for this attribute is an unlimited number.

HTML 4.01 Specification

「maximum number of characters」と記載のあるとおり、指定するのは文字数。

iモードHTMLの仕様を確認してみると、次の通りだった。

<INPUT>
関連属性
type=”text | password | checkbox | radio | hidden | submit | reset”
name=”フィールド名”
value=”データ”
size=”文字数”
maxlength=”最大バイト数”
checked
accesskey=”char” ダイレクトキー機能(イージーフォーカス)
iモード対応HTMLタグ一覧

docomoでは最大バイト数との表記が・・・。なんか嫌な予感がする。

SoftBankは次のような仕様だ。

3.12.2.input:入力

maxlength
コントロールがtext もしくはpassword の場合に入力データ長の上限を与える。

ウェブコンテンツ開発ガイド

「入力データ長」という表記なので、バイト数なのか文字数なのかどっちとも判断しづらい。

実機調査の結果

やっぱり実機調査するしかない。ということで、実機テスト用に次のようなHTMLを準備してサーバーにアップしておいた。

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
</head><body>
<form action="maxlength.html" method="POST">
<input type="text" name="a" maxlength="2"><br>
<input type="submit" value="送信">
</form>
</body></html>

実機テストの結果はコチラ(PCブラウザも入れてある)。

 
機種 maxlengthの単位
IE 8 文字数
Firefox 3.6 文字数
Chrome 4.1 文字数
docomo N-06A バイト数
docomo N904i バイト数
docomo N506iS バイト数
SoftBank 932SH 文字数
SoftBank 920P 文字数
au G9 文字数
au W61K 文字数
iPhone 3GS 文字数

この結果を見ると、docomoだけがバイト数として扱っているようだ。SoftBank C型・P型の場合もバイト数として扱っていた記憶があるけど、C型とP型は3月末でサービスが終了したから該当しなくなった。

ちなみにバイト数というのは、シフトJIS換算のバイト長のこと。HTMLのキャラクタエンコーディングをUTF-8にしても、結局はシフトJISでの長さとなる。

影響範囲と対応方法

maxlength属性の仕様の違いが最も影響するのは、DBアクセスがからんできたとき。テーブル定義にもよるけど、フォームで入力したテキストをそのままDBに入れてしまうと、DBアクセスでエラーになる可能性がある。

たとえば、Oracleでフィールド定義が VARCHAR2(20) のカラムに日本語を格納する場合、データベースキャラセットがシフトJISなら全角10文字まで入る。PCサイトが前提ならmaxlength=”10″ と指定するだけでOKだけど、いざdocomoのブラウザで見てみると全角5文字までしか入らない。

ここでmaxlength=”20″に変更し、docomoでも全角10文字まで入力できるように変更すると問題が発生する。SoftBankやauでは全角20文字まで入力できてしまうから、入力された文字列でそのままDB更新を行うと、SQLでエラーとなってしまうのだ。

対処方法は3つ。

(A)フォーム送信先で入力データのバイト数チェックを行う

入力フォームで入力された文字列をチェックし、バイト数をチェックする方法だ。この方法を取る場合は、文字列の長さが超過している場合に入力フォームに再度誘導し再入力を促す、といった遷移変更が必要になる。

文字列のバイト数チェックはJavaなら次のようなコードで対応できる。

request.setCharacterEncoding("Windows-31J");
String name = request.getParameter("name");
if (name.getBytes("Windows-31J").length > 20) {
  // 全角10文字を超えているので、ユーザーに再入力を促す
}
// 正常(全角10文字以内)

 

(B)docomoだけmaxlengthの値を変更する

docomoはバイト数換算、それ以外は文字数換算という特徴を利用する方法。docomoからアクセスされたときはmaxlength=”20″とし、それ以外の場合はmaxlength=”10″とすれば、どの機種でも全角10文字まで入力できる。ただし、機種判定処理が必要となる。

roundaboutを使えば、キーワード置換機能やスペック指定PIを利用してdocomoだけmaxlength=”20″として出力することができる。

(C)DBのカラム長を変更する

DBに全角10文字を超えるデータが入っても良いという前提にはなるけど、フィールド定義を VARCHAR2(40) に変更するという方法。SQLエラーを回避することができる。

まとめ

そおすすめ記事: 非公開情報だよ!au GPSの使い方 | 株式会社シンメトリック公式ブログ | 

maxlength属性の仕様の違いを吸収するために行う労力は実に大きい!でもアプリケーション側で何らかの対応を行わないと、SQLエラーになったり文字列の後ろが切れてしまうとかいろいろと不都合が出てくる。

docomoの最新機種でもmaxlengthはなぜかバイト数換算・・・。モバイルサイト構築の際は今後も注意が必要だろう。

(参考)