IEでのa要素の各属性について

色々あってa要素でURLをパースするというコードを書いていて色々はまったのでまとめます。

IE6-8でのa.hrefの上限

  • IE6,7:4096bytes
  • IE8:4121bytes

でした。
なお、Firefox,Google Chrome,Safariは1MBとか普通に扱えます。
使わないけど。
http://jsdo.it/monjudoh/8Fm6/read

各属性の取得状況

a.hrefにURLを代入して各属性がどうなるか調べてみました。

  • URLの長さが短い⇔上限超え
  • outerHTMLハックを使わない⇔使う
    • a.hrefにURLを代入後、別の要素のinnerHTMLにa.outerHTMLを代入し、そのfirstChild(a要素)の各属性を見ること

の二軸を変えて調べてみました。
http://jsdo.it/monjudoh/sc82

IE6

a.hrefへの代入で更新される属性は以下の3つのみ(なのでURLのパースをするにはouterHTMLハックが必要になる)

  • href
  • search
  • hash

上限超えのURLを代入すると、各属性(更新された分)を参照するだけでErrorが投げられる

---url.length:10,use outerHTML:false
href:[/a?111#hash] 
, search:[?111]
, protocol:[]
, hostname:[]
, port:[]
, pathname:[]
, hash:[#hash]
---url.length:4097,use outerHTML:false
href:[/a?1(中略)1#has] 
, search:[[object Error]]
, protocol:[]
, hostname:[]
, port:[]
, pathname:[]
, hash:[[object Error]]
---url.length:10,use outerHTML:true
href:[http://jsrun.it/a?111#hash] 
, search:[?111]
, protocol:[http:]
, hostname:[jsrun.it]
, port:[80]
, pathname:[a]
, hash:[#hash]
---url.length:4097,use outerHTML:true
href:[[object Error]] 
, search:[[object Error]]
, protocol:[[object Error]]
, hostname:[[object Error]]
, port:[[object Error]]
, pathname:[[object Error]]
, hash:[[object Error]]
IE7

a.hrefへの代入で更新される属性は以下の4つ(IE6に比べるとpathnameが追加されている)
protocolも更新されているがなぜか"http:"になるべきところが":"になっている

  • href
  • search
  • pathname
  • hash

上限超えのURLを代入すると、各属性(更新された分)は末尾が切れるなどする。
outerHTMLハックを使っても以下のような問題が残る。

  • 末尾は切れる
  • protocolが"about:"になってしまう
  • hostname,portが空文字
---url.length:10,use outerHTML:false
href:[/a?111#hash] 
, search:[?111]
, protocol:[:]
, hostname:[]
, port:[]
, pathname:[a]
, hash:[#hash]
---url.length:4097,use outerHTML:false
href:[/a?1(中略)1#has] 
, search:[?1(中略)1]
, protocol:[:]
, hostname:[]
, port:[]
, pathname:[a]
, hash:[#has]
---url.length:10,use outerHTML:true
href:[http://jsrun.it/a?111#hash] 
, search:[?111]
, protocol:[http:]
, hostname:[jsrun.it]
, port:[80]
, pathname:[a]
, hash:[#hash]
---url.length:4097,use outerHTML:true
href:[about:/a?1(中略)1#has] 
, search:[?1(中略)1]
, protocol:[about:]
, hostname:[]
, port:[]
, pathname:[a]
, hash:[#has] 
IE8

a.hrefへの代入で更新される属性は以下の4つ
protocolも更新されているがなぜか"http:"になるべきところが":"になっている
IE7と同様だがa.hrefにprotocol,hostnameを除いたURLを代入しても
protocolから始まるフルのURLにhref属性が更新される点が違う。

  • href
  • search
  • pathname
  • hash

outerHTMLハックを使うと(IE7と違い)短いURLでも以下のような問題が発生する。
なお、フルのURLを代入する分には問題ない。

  • protocolが"about:"になってしまう
  • hostname,portが空文字

上限超えのURLを代入すると、何故かhashが反映されない。
hash属性も取れないしhref属性にもhash分がない。

---url.length:11,use outerHTML:false
href:[http://jsrun.it/a?1111#hash] 
, search:[?1111]
, protocol:[:]
, hostname:[]
, port:[]
, pathname:[a]
, hash:[#hash]
---url.length:4122,use outerHTML:false
href:[http://jsrun.it/a?1(中略)1] 
, search:[?1(中略)1]
, protocol:[:]
, hostname:[]
, port:[]
, pathname:[a]
, hash:[]
---url.length:11,use outerHTML:true
href:[http://jsrun.it/a?1111#hash] 
, search:[?1111]
, protocol:[about:]
, hostname:[]
, port:[]
, pathname:[a]
, hash:[#hash]
---url.length:4122,use outerHTML:true
href:[http://jsrun.it/a?1(中略)1] 
, search:[?1(中略)1]
, protocol:[about:]
, hostname:[]
, port:[]
, pathname:[a]
, hash:[]
Firefox3.6

4KB程度では上限全然行かないので短いURLのみ。
また、outerHTMLは使えないのでouterHTMLハック使用版はなしで。

  • a.hrefにprotocol,hostnameを除いたURLを代入してもprotocolから始まるフルのURLにhref属性が更新される
  • portは80の場合は空文字
  • pathnameは最初の"/"が付く
href:[http://jsrun.it/a?1111#hash] 
, search:[?1111]
, protocol:[http:]
, hostname:[jsrun.it]
, port:[]
, pathname:[/a]
, hash:[#hash]
Google Chrome8
  • a.hrefにprotocol,hostnameを除いたURLを代入してもprotocolから始まるフルのURLにhref属性が更新される
  • portは80の場合はなぜか0
  • pathnameは最初の"/"が付く

outerHTMLハック使用有無で違いはなし。

href:[http://jsrun.it/a?1111#hash] 
, search:[?1111]
, protocol:[http:]
, hostname:[jsrun.it]
, port:[0]
, pathname:[/a]
, hash:[#hash]
Safari5
  • a.hrefにprotocol,hostnameを除いたURLを代入してもprotocolから始まるフルのURLにhref属性が更新される
  • portは80の場合はなぜか0
  • pathnameは最初の"/"が付く

outerHTMLハック使用有無で違いはなし。
Google Chrome8と同じ結果

href:[http://jsrun.it/a?1111#hash] 
, search:[?1111]
, protocol:[http:]
, hostname:[jsrun.it]
, port:[0]
, pathname:[/a]
, hash:[#hash]

結論

URLのパースにa要素を使ってもクロスブラウザ対応を考えるとあまり幸せになれないのではないか