エスケープについて

[新着] Webテンプレートを仮オープンしました



0   名前: 7go : 2007/03/09(金) 16:24  [URL]  ID:LKDMQty3 sub-t1
http://7go.biz/moba3/archives/2007/0308085152.htmlのページにJAVASCRIPTと実体参照ということを書きました。でこのことを書いているときにでてきたわからないことです。
<input type="button" value="ボタン" onclick="a('引数')">
のような関数a()に引数を渡すときなど、たとえば引数に'と"が使われている場合どうやってエスケープするのでしょうか?

'か"どちらかの場合はonclick="a('\'')"もしくはonclick='a("\"")'とわかるのですが両方の場合単純に\'\"とエスケープしてもダメのようです。onclick=a('\'"')ということはできますが、この例だけでなくdocument.writeを使う時や色々な場面で利用することがあるかもしれないのできちんとしたものが知りたいです。よろしくお願いします。

1   名前: 某制作さん : 2007/03/09(金) 16:24  ID:gFY2524F sub-Q5
なんてお伝えすれば良いか難しいので
【sample】
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis" />
<title>無題ドキュメント</title>
</head>
<script type="text/javascript">
onload = function test1(txt){
alert('\'\"');
}
</script>

<body>
<script type="text/javascript">
function test(txt){
alert(txt);
}
</script>
<a onclick="test('\'\"');">aaaaaaaaaaa</a>
</body>
</html>


上のスクリプトは
ほとんど同じ文ですが
読み込み時に作動しますが
下のスクリプトはエラーになります。

解決策としては
1. &quot;や&acute;を引数に使う
2. scriptタグ内でvar ● = "\'\"";
としHTML上の引数には●を使う。


こんな感じで
いかがでしょうか?

2   名前: 某制作さん  : 2007/03/09(金) 16:24  ID:gFY2524F sub-Q5
補足

解決策としては
1. &quot;や&acute;を引数に使う
<a onclick="test('&quot;&acute;');">aaaaaaaaaaa</a>

2. scriptタグ内でvar ● = "\'\"";
としbody上のイベントハンドラ内(onclick)の引数には●を使う。
<script type="text/javascript">
var xxx = "\"\'";
function test(txt){
alert(txt);
}
</script>
・・・・・・・・・・・・・・・・
<a onclick="test(xxx);">aaaaaaaaaaa</a>

3   名前: 匿名 : 2007/03/09(金) 16:24  ID:Z/T9lFdK sub-kJ
>>0
原則、まず HTML(XML)としてパースされ、次にスクリプトエンジンに渡される。このことさえ理解していれば、どこで実体参照を使うべきか、どこで JavaScript エスケープが必要かは、見当が付くはず。

# なお、要素内の CDATA の実体参照は展開されないが、属性内 CDATA の実体参照は常に展開される(ように見える)。したがって、属性内の & は必ず実体参照にしなければならない。

> onclick=a('\'"')ということはできますが

(、) は名前文字ではないから、引用符の省略は不可。HTML として不正。

> たとえば引数に'と"が使われている場合

まあ、そんなややこしいエスケープをするくらいなら、いくつかの段階に分けて文字列連結するけどね。と言うか、個人的にはできるだけ文字列操作は避けて、専用のインタフェース(DOM など)を使う。

4   名前: 7go : 2007/03/09(金) 16:24  [URL]  ID:LKDMQty3 sub-t1
忙しいところ教えていただき有難うございます。感謝いたします。

某制作さんへ
1.は、やってみましたが&acute;と '(シングルコーテーション) は同じものですか?
実験的に
A、<input type="button" value="ボタン" onclick="alert(&acute;あ&acute;)">B、<input type="button" value="ボタン" onclick="alert(&#039;あ&#039;)">
でやって見たらAはエラーになるのでシングルコーテーションでは無いのではないかと思うのですがどうでしょう。ネットでも調べましたが違うと思われます(自信なし)。

2.onclick="test(xxx)" の引数は自分で考えた文字を入れるのではなく例えばWEBサービスからXMLのデータをもらいタイトルを切り出し引数にする場合です。なので自分ではどのような文字が入るのかは不明の状態になります。(XMLからデータを切り出すとき引数に連番、配列に文字でできるとは思いますが、引数にはできないのでしょうか?)

匿名さんへ
「いくつかの段階に分けて文字列連結する」とは具体的にどのようにすればいいですか?
専用のインタフェース(DOM など)とは具体的にどのようなものですか?

(オブジェクト指向的なSCRIPTや高度なものは勉強しようと眺めてはいますが頭が切り替わらずうかびません)


結論として引数に' "をふたつ入れることはできないのでしょうか?教えてくださいお願いします。

5   名前: 匿名 : 2007/03/09(金) 16:24  ID:Z/T9lFdK sub-kJ
<script type="text/javascript">function a (s) { return s; }</script>

<!-- "Is's a pen." -->
<p onclick="alert (a ('&quot;It\'s a pen.&quot;'));">TEST</p>

<p onclick="alert (a ('&#34;It\'s a pen.&#34;'));">TEST</p>
<p onclick="alert (a ('&#34;It\&#39;s a pen.&#34;'));">TEST</p>
<p onclick="alert (a ('&#34;It&#92;&#39;s a pen.&#34;'));">TEST</p>

<p onclick="alert (a ('\u0022It\u0027s a pen.\u0022'));">TEST</p>

6   名前: 7go : 2007/03/09(金) 16:24  ID:z9piv2Cn sub-2w
某制作さん、匿名さん回答ありがとうございました。

きちんと動作しました。私の読解力不足で某制作さんが1番目の方法としてあげた&quot;や&acute;を引数に使うも同じ事を言っていたのですね。すいませんでした。

くどくてすいませんが、さらにお尋ねします。
<p onclick="alert (a ('&quot;It\'s a pen.&quot;'));">TEST</p>
がきちんと動作するのは、
まずHTMLの部分が解釈される時は
<p onclick="alert (a ('&quot;It\'s a pen.&quot;'));">TEST</p>
となっているのでエラーにならず、次にJAVASCRIPTが実行されるとき(onclick時)には、
実体参照が展開され
alert (a ('"It\'s a pen."'));
となるからと言う事でいいのでしょうか?

うまく伝えれないのですが、
逆に言うと
JAVASCRIPTが実行されるときには
<p onclick="alert (a ('"It\'s a pen."'));">TEST</p>
と評価されるのではなく
JAVASCRIPTの実行部分だけ
alert (a ('"It\'s a pen."'));
が評価の対象になるのでエラーにならないと言う事でしょうか?

やり方はわかったのですが考え方がなぜそうなるのかいまいちぼやーっとしているのでしつこいと思いますがお願いいたします。


7   名前: 匿名 : 2007/03/09(金) 16:24  ID:Z/T9lFdK sub-kJ
# 何だよ >>5 の Is's って……脳が腐ってやがる OTL。

属性値内で ' と " を両方使いたい場合、次のように間違う人が多い。
onclick="alert ('I said, \"It\'s a pen.\"'); "

だが、>>3 で言ったことをもう一度繰り返すが、HTML はまず HTML としてパースされる。この当たり前の事実を忘れてはいけない。

HTML パーサから見れば、この属性値の範囲は
onclick="alert ('I said, \"It\'s a pen.\"'); "

であり、残りは不明な属性として捨てられる。このスクリプトデータは、当然エラーとなる。

HTML パーサがこのような誤解をしないようにするには:

(a). 引用符を実体参照に。この場合、属性値内(RCDATA)で実体参照が展開されることを利用して、正しいスクリプトデータへの展開も同時に行う。
onclick="alert ('I said, &quot;It\'s a pen.&quot;'); "
↓
alert ('I said, "It\'s a pen."');

(b). 引用符を JavaScript 的にエスケープしておけば、HTML パーサが誤解する余地などない。
onclick="alert ('I said, \u0022It\'s a pen.\u0022'); "

まあ、異なる言語を混在させないようにすれば、こんな面倒なことをせずに済むわけで。スタイルシートを分離させるのと同様、スクリプトデータも分離させた方が良い。

8   名前: 7go : 2007/03/09(金) 16:24  [URL]  ID:LKDMQty3 sub-t1
懇切丁寧に有難うございました。

理解できてスッキリしました。

こんなことまで簡単にわかっているなんてあこがれます。

一覧へ戻る