あなたの質問は少し不明確ですが、私はあなたが言っていることを推測し、すべてのケースをカバーし、少し付加価値を与えるようにします;)
JSPページにサーバー側の文字列があると仮定します。値は次のとおりです。
5: "White", 6: "Yellow", 7: "Pink"
それがどのように見えるか
<%
String data = "5: \"White\", 6: \"Yellow\", 7: \"Pink\"";
%>
そして今、それをドキュメントに書き込みたいので、for
後でクライアント側のコードでそれを行うことができます。
その意味で、いくつかのケースを区別する必要があります。
サーバーがそれを応答ドキュメントに書き込むとき、それは文字列ですが、クライアントコードはさまざまな方法でこの値を取得できます。それらすべてにおいて、サーバーはクライアントがデータにアクセスできるように特定の方法でデータを書き込む必要がありますが、有効性のルールは異なります。
オブジェクトリテラルを書く
実は-それがあなたがやろうとしていることだと思います。クライアントコードはそれを文字列としてではなく、オブジェクトリテラルとして取得します。
<script>
var sObjData = {<%= safeJs(data) %>};
</script>
この選択の制限は、サーバーコード(内<%%>
)からのものとマークアップ(から外<%%>
)からのものはすべて、有効なJavaScriptオブジェクトリテラルとして連携する必要があるということです。このオブジェクトリテラルの合法性を損なう可能性のあるものはたくさんあります。たとえば、文字列の破損、コンマの欠落、コロンの欠落などです。これが推奨される方法ですが、自分が何をしているのかを知る必要があります。この知識をギャップすることをお勧めします。あなたの例は良いスタートです。
あなたの例では、これは有効なJavaScript Object-Literalにレンダリングされ、問題はありません。
<script>
var sObjData = {5: "White", 6: "Yellow", 7: "Pink"};
</script>
これは完全に合法的なオブジェクトリテラルでありfor
、あなたと同じように使用できます。
あなたの例はあなたのケースの単純化であるかもしれません、そしてあなたが使う文字列はあなたの実行を壊すかもしれません。サーバーからクライアントコードへの文字列の処理方法は次のとおりです。
JavaString文字列を書く
この場合の制限(data
JavaSctipt strinbngsを壊す可能性のある文字列内の文字)は、javascriptではエスケープする必要があります。
ここでは、値全体を扱いdata
ますが、この中に入れるすべての値に対して同じことをしたい場合があることを覚えておいてくださいdata
。
これは、JavaScriptのJava文字列をエスケープすることを説明する最も簡単な実装です。
<%!
String safeJs(String data){
return data.replace("\"","\\\"") //why three? two emit a sigle \ and the third escape the "
.replace("'","\\'")
.replace("\n","\\n") //why two? you're not escaping n, your're emitting \ and n
.replace("\r","\\r"); // that will render as escaping for the client code
}
%>
<script>
var sObjData = '<%= safeJs(data) %>';
<script>
この部分は、サーバーからクライアントにすべてのデータを取得し、クライアントがアクセスできるようにすることを保証します。そこから-データを配信してクライアントで解析するのは、独自のプロトコルの問題です。
ただし、これは常に推奨されるわけではありません。ブラウザがコンパイルされたコードで解析を処理し、スクリプトコードに既製のオブジェクトを提供するため、提供するすべてがオブジェクトリテラルとして定式化できる場合(はるかに優れています)。 。
独自の文字列プロトコルを解析したい場合を除いて、一見すると、次のように同じ結果が得られます。なぜわざわざするのでしょうか。あなたの価値観により良いsafeJs
。
<script>
var sObjData = '<%= safeJs(data) %>';
var oObjData = eval("{" + oObjData + "}");
<script>
TextAreaのコンテンツに文字列を書き込みます
これは、サーバーとHTMLクライアント間で文字列を渡す最も堅牢な方法です-壊れることがあるのは、データ文字列にTextAreaの終了タグが含まれている場合だけだからです。
テキスト領域は改行の影響を受けず、引用符(シングルおよびダブル)に影響されません。唯一の弱点は、独自の終了タグです。
「」を「<textarea>」に置き換え、「」を「<textarea>」に置き換えることに注意してください。
IDをテキスト領域に割り当ててstyle="display:none"
配置することで、UIに煩わされることなく、アクセスできるようになります。
<textarea style="display:none" id="txtData"><%=data.replace("</","</")%></textarea>
<script>
var s = document.getElementById("txtData");
</script>
Selectでオプションを作成する
DHTMLのトリックはcreateElement
機能しますが、面倒でパフォーマンスが非常に低いため、私はめったに使用しません。ただし、オブジェクトリテラルを適切に記述できれば、機能するはずです。
HTMLを挿入する
選択を作成してそれを設定しようとする代わりに、それをDOMに完全に挿入する方が高速で信頼性が高くなります。
そのために次のユーティリティを使用します。
function getStringBuffer(){
var bfr = [];
bfr.add = function() {
for(var i=0;i<arguments.length;i++) {
this[this.length] = arguments[i];
}
}
bfr.toString = function() { return this.join("") }
return bfr;
}
ラップインして無名関数を作成し、それを即座に実行します。これにより、この作業用に宣言された変数がグローバルスコープを汚染しないことが保証されます(function(){
。})()
最初の方法-使用document.write
:
<script>
(function(){
var HTML = getStringBuffer();
var k;
HTML.add("<select id='selectObj'>");
for (k in myOpts) {
HTML.add("<option value='", k, "'>", myOpts[k],"</option>");
}
HTML[HTML.length] = "</select>";
document.write(HTML); //note the overriden toString method that will be called here
})();
</script>
2番目の方法-innerHTMLを使用する代わりにdocument.writeを使用する-コンテナタグを使用して選択の場所をマークし、DOMの読み込みが完了した後でもそこに挿入します。
これは最初の方法と同じですが、1つの違いがあります。代わりdocument.write(HTML);
に、コンテナを配置し<span id="oSelectPlace"></span>
、選択する場所を指定してから、
document.getElementById("oSelectPlace").innerHTML = HMTL;