Каковы аргументы против включения сценариев на стороне сервера в блоки кода JavaScript?

Некоторое время я выступал против встраивания тегов на стороне сервера в код 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. Разделение кода: мы должны максимально разделять технологии веб-страниц.

Причина этого заключалась в том, что разработчику не нужно было определять константу в двух местах. Они рассудили, что, поскольку это значение находится под их контролем, оно не подлежит внедрению скриптов. Это уменьшило мое обоснование (1) до «Мы пытаемся сохранить стандарты простыми, и определение случаев исключения может сбить людей с толку».

Аргументы модульного тестирования и разделения кода также не выдерживали никакой критики, так как сама страница представляла собой ужасную смесь HTML, JavaScript, ASP.NET, CSS, XML... вы называете это, это было там. Никакой код, который должен был быть включен в эту страницу, не мог быть протестирован.

Так что я почувствовал себя немного педантом, настаивающим на том, чтобы код был изменен, учитывая обстоятельства.

Есть ли какие-либо дополнительные аргументы, которые могли бы поддержать мои рассуждения, или я на самом деле немного педантичен в этой настойчивости?


person James Wiseman    schedule 17.01.2011    source источник
comment
В чем разница между использованием кода на стороне сервера для вывода javascript и использованием кода на стороне сервера для вывода HTML? Если надо, то надо.   -  person Paddy    schedule 17.01.2011
comment
Ваше предположение ошибочно - в приведенном вами примере кода нет ничего плохого.   -  person meagar    schedule 17.01.2011
comment
@Paddy, @meagar: Хотя я ценю ваши комментарии, я надеялся на более подробное обсуждение того, почему?, как это предусмотрено @Pointy в его превосходном ответе. Мой первоначальный вопрос напрямую касается вопроса @ Пэдди (в чем разница ...), объясняя при этом, почему утверждение @ meagar (ваше предположение ошибочно) само по себе ошибочно.   -  person James Wiseman    schedule 17.01.2011
comment
На самом деле это не встраивание тегов на стороне сервера в код JavaScript, а совсем наоборот. Подумай об этом   -  person Your Common Sense    schedule 17.01.2011
comment
Просто подумайте о том, в каком порядке выполняются эти инструкции. Что будет выполняться первым?   -  person Your Common Sense    schedule 17.01.2011
comment
Да, но согласно этому аргументу все, что в действительности содержит скрипты на стороне сервера, на самом деле является просто встроенным кодом внутри скрипта. Хотя теоретически это может иметь место, в повседневной практике мы ссылаемся на абстракцию, которая подразумевает, что сценарий встроен, а не наоборот.   -  person James Wiseman    schedule 17.01.2011
comment
да, ты понял! Так работают шаблоны на стороне сервера. Просто изучите его лучше. Есть миллионы сайтов, которые работают таким образом. И на вашем месте я бы избегал людей, которые говорят, что скрипт на стороне сервера встроен. Они понятия не имеют, о чем говорят.   -  person Your Common Sense    schedule 17.01.2011


Ответы (3)


  • Внедрение скрипта: тег на стороне сервера может содержать код, который может сломать код JavaScript.

Так что пишите код правильно и убедитесь, что значения корректно экранируются при введении в контекст JavaScript. Если ваш фреймворк не включает инструмент "цитирования" JavaScript (подсказка: поддержка JSON, вероятно, все, что вам нужно), напишите его.

  • Модульное тестирование. Сложнее изолировать блоки кода для тестирования

Это хороший момент, но если серверу необходимо добавить что-то на страницу для использования кода, тогда это необходимо. Я имею в виду, что бывают случаи, когда это просто необходимо сделать. Хороший способ сделать это, чтобы страница содержала какой-то минимальный блок данных. Таким образом, обработанный сервером JavaScript на странице на самом деле не является тестируемым «кодом», это просто данные. Настоящий клиентский код, включенный в файлы .js, может найти данные и использовать их.

Таким образом, страница может содержать:

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

Теперь ваш прекрасно инкапсулированный чистый код JavaScript в файлах «.js» просто должен проверить наличие window.pageData, и все готово.

  • Разделение кода: мы должны максимально разделять технологии веб-страниц.

Согласен, но это просто факт, что иногда данные на стороне сервера должны управлять поведением на стороне клиента. Создание скрытых DOM-узлов исключительно для хранения данных и соблюдения ваших правил само по себе является довольно уродливой практикой.

Правила кодирования и эстетика — это хорошо. Однако следует быть прагматичным и смотреть на все в перспективе. Важно помнить, что контекстом таких правил не всегда является Совершенное Божественное Творение, и в случае с HTML, CSS и JavaScript я думаю, что этот факт очевиден. В такой несовершенной среде жесткие правила могут заставить вас выполнять ненужную работу и код, который на самом деле сложнее поддерживать.

редактировать а вот еще кое-что, о чем я только что подумал; своего рода компромисс. «Трюк», популяризированный (частично) бандой jQuery с их средством «микрошаблонов» (извиняюсь перед веб-гением, который на самом деле наткнулся на это первым), заключается в использовании тегов <script>, которые являются своего рода «стерилизованными»:

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

Теперь сам браузер даже не будет выполнять этот скрипт - атрибут "type" не является чем-то, что он понимает как код, поэтому он просто игнорирует его. Однако браузеры делают доступ к содержимому таких скриптов, поэтому ваш код может найти скрипт по значению "id", а затем с помощью какой-либо безопасной библиотеки JSON или встроенного API браузера, если он доступен, проанализировать нотацию. и извлечь то, что ему нужно. Значения по-прежнему должны быть правильно заключены в кавычки и т. д., но вы несколько безопаснее от дыр XSS, потому что они анализируются как JSON, а не как «живой» полноценный JavaScript.

person Pointy    schedule 17.01.2011

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

Для меня это лучший аргумент, чем любой аргумент, который вы можете привести против него. Это принцип DRY. И это значительно повышает удобство сопровождения кода.

Каждое руководство/правило стиля, доведенное до крайности, приводит к анти-шаблону. В этом случае ваша настойчивость в разделении технологий нарушает принцип DRY и потенциально может затруднить сопровождение кода. Даже сам DRY, если его довести до крайности, может привести к анти-шаблону: softcoding .

Сопровождаемость кода — прекрасный баланс. Руководства по стилю помогут сохранить этот баланс. Но надо знать, когда эти самые проводники помогают, а когда сами становятся проблемой.


Обратите внимание, что в приведенном вами примере код не нарушит выделение или синтаксический анализ синтаксиса (даже stackoverflow правильно его выделяет), поэтому аргумент IDE не будет работать, поскольку IDE все еще может правильно анализировать этот код.

person slebetman    schedule 17.01.2011

  1. это просто становится нечитаемым. Вы должны присмотреться, чтобы разделить разные языки. Если JavaScript и смешанный язык используют одни и те же имена переменных, все становится еще хуже. Это особенно сложно для людей, которым приходится смотреть на код других людей.

  2. Многие IDE имеют проблемы с подсветкой синтаксиса сильно смешанных документов, что может привести к потере автозавершения, правильной подсветки синтаксиса и так далее.

  3. Это делает код менее пригодным для повторного использования. Подумайте о функции JavaScript, которая выполняет стандартную задачу, например, повторяет массив вещей. Если вы отделите логику JavaScript от данных, которые она перебирает, вы сможете использовать одну и ту же функцию во всем приложении, и изменения в этой функции нужно будет вносить только один раз. Если данные, которые он перебирает, смешиваются с выходным циклом JavaScript, вы, вероятно, в конечном итоге повторяете код JavaScript только потому, что смешанный язык имеет дополнительный оператор if перед каждым циклом.

person acme    schedule 17.01.2011
comment
Спасибо, я не учел аргумент IDE. - person James Wiseman; 17.01.2011