Firefox の location.hash は、他のブラウザと異なり、URI デコードした結果を表すのは、よく知られていると思いますが、なんど制御コードに限ってデコードしない例外があるようです。試しているのは Firefox 3.6 です。
例えば、改行入りのテキストを location.hash で状態を保持しようとすると、改行コードは CR/LF にデコードされず、%0D%0A のままとなってしまいます。なんじゃこれ。何か勘違いしているのかなぁ。
試しに ASCII コードをぜんぶ試してみたところ、
for (var i = 0x0; i <= 0x7f; i++) { var hex = Number(i).toString(16); var ch = String.fromCharCode(i); location.href = '#' + encodeURIComponent(ch); console.log('0x' + hex + ': ' + location.hash); }制御コードは、デコードされないことを知りました。HTML や DOM の仕様にそぐわないからだろうか。それとも、脆弱性に関するものだろうか。
0x0: #%00
0x1: #%01
0x2: #%02
0x3: #%03
0x4: #%04
0x5: #%05
0x6: #%06
0x7: #%07
0x8: #%08
0x9: #%09
0xa: #%0A
0xb: #%0B
0xc: #%0C
0xd: #%0D
0xe: #%0E
0xf: #%0F
0x10: #%10
0x11: #%11
0x12: #%12
0x13: #%13
0x14: #%14
0x15: #%15
0x16: #%16
0x17: #%17
0x18: #%18
0x19: #%19
0x1a: #%1A
0x1b: #%1B
0x1c: #%1C
0x1d: #%1D
0x1e: #%1E
0x1f: #%1F
0x20: #
0x21: #!
0x22: #"
0x23: ##
0x24: #$
0x25: #%
0x26: #&
0x27: #'
0x28: #(
0x29: #)
0x2a: #*
0x2b: #+
0x2c: #,
0x2d: #-
0x2e: #.
0x2f: #/
0x30: #0
0x31: #1
0x32: #2
0x33: #3
0x34: #4
0x35: #5
0x36: #6
0x37: #7
0x38: #8
0x39: #9
0x3a: #:
0x3b: #;
0x3c: #<
0x3d: #=
0x3e: #>
0x3f: #?
0x40: #@
0x41: #A
0x42: #B
0x43: #C
0x44: #D
0x45: #E
0x46: #F
0x47: #G
0x48: #H
0x49: #I
0x4a: #J
0x4b: #K
0x4c: #L
0x4d: #M
0x4e: #N
0x4f: #O
0x50: #P
0x51: #Q
0x52: #R
0x53: #S
0x54: #T
0x55: #U
0x56: #V
0x57: #W
0x58: #X
0x59: #Y
0x5a: #Z
0x5b: #[
0x5c: #\
0x5d: #]
0x5e: #^
0x5f: #_
0x60: #`
0x61: #a
0x62: #b
0x63: #c
0x64: #d
0x65: #e
0x66: #f
0x67: #g
0x68: #h
0x69: #i
0x6a: #j
0x6b: #k
0x6c: #l
0x6d: #m
0x6e: #n
0x6f: #o
0x70: #p
0x71: #q
0x72: #r
0x73: #s
0x74: #t
0x75: #u
0x76: #v
0x77: #w
0x78: #x
0x79: #y
0x7a: #z
0x7b: #{
0x7c: #|
0x7d: #}
0x7e: #~
0x7f: #%7F
ただ、今日のウェブアプリの作り方からすると、タブや改行コードも含めて状態を保持して欲しいところでもあり、次のように location.href から hash を取り出せば解決しそうな気がするのですが、このようなアプローチをとっている解説が見つからないのはなぜだろう?
window.onhashchange = function() { var hash = firefox ? (location.href.split('#')[1] || '') : location.hash; }参考にした情報などどなど。ただ、Firefox の仕様はどうなっているのかは分かりませんでした。