1

一段时间以来,我一直在反对在 JavaScript 代码中嵌入服务器端标签,但今天被一个似乎不相信的开发人员当场提出来

有问题的代码是一个遗留的 ASP 应用程序,尽管这在很大程度上并不重要,因为它同样适用于 ASP.NET 或 PHP(例如)。

有问题的示例围绕使用他们在服务器端代码中定义的常量展开。

'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 的可怕混合物……你说它,它就在那里。本页面中包含的所有代码都不可能进行单元测试。

因此,鉴于当时的情况,我发现自己有点像一个坚持要更改代码的书呆子。

是否有任何进一步的论据可以支持我的推理,或者我是否真的在这种坚持上有点迂腐?

4

3 回答 3

2
  • 脚本注入:服务器端标签可能包含可以破坏 JavaScript 代码的代码

因此,请正确编写代码并确保在将值引入 JavaScript 上下文时正确转义。如果您的框架不包含 JavaScript“引用器”工具(提示:JSON 支持可能就是您所需要的),请编写一个。

  • 单元测试。更难隔离代码单元以进行测试

这是一个很好的观点,但如果服务器需要将内容放入页面以供代码使用,那么它是必要的。我的意思是,有时必须这样做。一个好的方法是让页面包含某种最小的数据块。因此,页面上的服务器端 JavaScript 实际上不是要测试的“代码”,它只是数据。.js 文件中包含的真实客户端代码可以找到数据并使用它。

因此,该页面可能包含:

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

现在,您在“.js”文件中封装良好的纯 JavaScript 代码只需检查 .window.pageData就可以了。

  • 代码分离:我们应该尽可能地将网页技术分开。

同意,但这只是一个事实,有时服务器端数据需要驱动客户端行为。仅仅为了存储数据和满足规则而创建隐藏的 DOM 节点本身就是一种非常丑陋的做法。

编码规则和美学是好事。但是,一个人应该务实,并以正确的眼光看待一切。重要的是要记住,这些规则的上下文并不总是完美的神圣创造,在 HTML、CSS 和 JavaScript 的情况下,我认为这一事实非常清楚。在这样一个不完美的环境中,强硬的规则可能会迫使您进行不必要的工作和实际上更难维护的代码。

编辑——哦,这是我刚刚想到的其他东西;一种妥协。jQuery 帮用他们的“微模板”工具(向实际上首先想到这一点的网络天才道歉)(部分)普及的“技巧”是使用<script>某种“中性”的标签:

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

现在浏览器本身甚至不会执行那个脚本——“类型”属性不是它理解为代码的东西,所以它只是忽略它。但是,浏览器确实使此类脚本的内容可用,因此您的代码可以通过“id”值找到脚本,然后通过一些安全的 JSON 库或本地浏览器 API(如果可用)解析符号并提取它需要的内容。这些值仍然必须正确引用等,但是您对 XSS 漏洞更安全一些,因为它被解析为 JSON 而不是“实时”成熟的 JavaScript。

于 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 逻辑与其迭代的数据分开,您可以在整个应用程序中使用相同的函数,并且只需对该函数进行一次更改。如果它迭代的数据与 JavaScript 输出循环混合在一起,您可能最终会重复 JavaScript 代码,因为混合语言在每个循环之前都有一个额外的 if 语句。

于 2011-01-17T14:58:53.280 回答