1

私はしばらくの間、JavaScriptコードにサーバー側のタグを埋め込むことに反対していましたが、今日、納得がいかないように思われた開発者によってその場に置かれました。

問題のコードはレガシーASPアプリケーションでしたが、ASP.NETまたはPHP(たとえば)にも同様に適用できるため、これはほとんど重要ではありません。

問題の例は、ServerSideコードで定義した定数の使用を中心に展開されています。

'VB
Const MY_CONST: MY_CONST = 1
If sMyVbVar = MY_CONST Then
    'Do Something
End If

//JavaScript
if (sMyJsVar === "<%= MY_CONST%>"){
    //DoSomething
}

これに対する私の標準的な議論は次のとおりです。

  1. スクリプトインジェクション:サーバー側のタグには、JavaScriptコードを破壊する可能性のあるコードが含まれている可能性があります
  2. ユニットテスト。テスト用にコードのユニットを分離するのが難しい
  3. コードの分離:Webページのテクノロジーを可能な限り分離する必要があります。

これを行う理由は、開発者が2か所で定数を定義する必要がないようにするためです。彼らは、それが自分たちが制御した値であるため、スクリプトインジェクションの対象ではないと推論しました。これにより、(1)の正当性が「標準を単純に保つように努めており、例外ケースを定義すると人々が混乱する」という理由になりました。

ページ自体がHTML、JavaScript、ASP.NET、CSS、XMLの恐ろしい融合であったため、単体テストとコード分離の引数も水を保持しませんでした。このページに含まれる予定のコードは、単体テストできない可能性があります。

そのため、状況に応じて、コードが変更されたと主張するちょっとした衒学者のように感じました。

私の推論を支持するかもしれないさらなる議論はありますか、それとも私は実際、この主張に少し衒学者であるのですか?

4

3 に答える 3

2
  • スクリプトインジェクション:サーバー側のタグには、JavaScriptコードを破壊する可能性のあるコードが含まれている可能性があります

したがって、コードを適切に記述し、JavaScriptコンテキストに導入されたときに値が正しくエスケープされていることを確認してください。フレームワークにJavaScriptの「quoter」ツールが含まれていない場合(ヒント:JSONサポートがおそらく必要なすべてです)、それを記述します。

  • ユニットテスト。テスト用にコードのユニットを分離するのが難しい

これは良い点ですが、サーバーがコードを使用するためにページに物をドロップする必要がある場合は、それが必要です。つまり、これを単に行わなければならない場合があります。これを行うための良い方法は、ページにある種の最小限のデータブロックを含めることです。したがって、ページ上のサーバーに接続されたJavaScriptは、実際にはテスト対象の「コード」ではなく、単なるデータです。.jsファイルに含まれる実際のクライアントコードは、データを見つけて使用できます。

したがって、ページには次のものが含まれる場合があります。

<script>
  (function(window) {
    window['pageData'] = {
      companyName: '<%= company.name %>',
      // etc
    };
  })(this);
</script>

これで、「。js」ファイルに適切にカプセル化された純粋なJavaScriptコードをチェックするだけで、準備が整いましwindow.pageDataた。

  • コードの分離:Webページのテクノロジーを可能な限り分離する必要があります。

同意しましたが、サーバー側のデータがクライアント側の動作を促進する必要がある場合があるのは事実です。データを保存し、ルールを満たすことのみを目的として非表示のDOMノードを作成すること自体は、かなり醜い方法です。

コーディングルールと美学は良いことです。ただし、実用的であり、すべてを視野に入れる必要があります。このようなルールのコンテキストは必ずしも完璧な神の創造物ではないことを覚えておくことが重要です。HTML、CSS、JavaScriptの場合、事実は明白だと思います。このような不完全な環境では、強硬なルールにより、実際には保守が難しい不要な作業やコードを強制される可能性があります。

編集—ああ、これは私が今考えた他の何かです。一種の妥協。「マイクロテンプレート」機能を備えたjQueryギャングによって(部分的に)普及した「トリック」(実際にこれを最初にヒットしたWebの天才への謝罪)は、<script>一種の「中立」なタグを使用することです。

<script id='pageData' type='text/plain'>
  {
    'companyName': '<%= company.name %>',
    'accountType': '<%= user.primaryAccount.type %>',
    // etc
  }
</script>

これで、ブラウザ自体はそのスクリプトを実行しません。「type」属性はコードとして理解されるものではないため、無視されます。ただし、ブラウザそのようなスクリプトのコンテンツを利用できるようにするため、コードは「id」値でスクリプトを検索し、安全なJSONライブラリまたは利用可能な場合はネイティブブラウザAPIを介して、表記を解析し、必要なものを抽出できます。値は適切に引用符で囲む必要がありますが、「ライブ」の本格的なJavaScriptとしてではなく、JSONとして解析されるため、XSSホールからある程度安全です。

于 2011-01-17T14:33:48.487 に答える
1

The reason for doing this was so that the developer did not have to define the constant in two places.

私にとって、これはあなたがそれに反対することができるどんな議論よりも良い議論です。それはDRYの原則です。また、コードの保守性が大幅に向上します。

極端なスタイルガイド/ルールはすべて、アンチパターンにつながります。この場合、テクノロジーの分離を主張すると、DRYの原則が破られ、コードの保守が困難になる可能性があります。極端な場合、DRY自体でさえ、アンチパターンにつながる可能性があります:ソフトコーディング

コードの保守性は微妙なバランスです。そのバランスを維持するのに役立つスタイルガイドがあります。しかし、あなたはそれらのガイドがいつ助けになり、いつ彼ら自身が問題になるのかを知る必要があります。


与えた例では、コードが構文のハイライトまたは解析を中断しないことに注意してください(stackoverflowでも正しくハイライトされます)。そのため、IDEはコードを正しく解析できるため、IDE引数は機能しません。

于 2011-01-17T15:32:57.100 に答える
0
  1. 単に読めなくなります。異なる言語を分割するには、詳しく調べる必要があります。JavaScriptと混合言語が同じ変数名を使用する場合、事態はさらに悪化します。これは、他の人のコードを見なければならない人にとっては特に難しいことです。

  2. 多くのIDEには、複雑に混在するドキュメントの構文の強調表示に問題があり、オートコンプリートや適切な構文の強調表示などが失われる可能性があります。

  3. コードの再利用性が低下します。一連のものをエコーするなど、一般的なタスクを実行するJavaScript関数について考えてみてください。JavaScriptロジックを反復するデータから分離すると、アプリケーション全体で同じ関数を使用でき、この関数への変更は1回だけ行う必要があります。反復するデータがJavaScript出力ループと混合されている場合、混合言語に各ループの前に追加のifステートメントがあるという理由だけで、JavaScriptコードを繰り返すことになります。

于 2011-01-17T14:58:53.280 に答える