Javascript最佳实践-使用服务器端的值

8
在过去的几年中,我一直使用客户端隐藏的 <input> 字段来存储服务器端的值,并在Javascript中使用它。例如,假设我需要从我的应用程序配置中获取一个Ajax超时值。我可能会在我的JSP中像这样存储它: <input type="hidden" id="ajaxTimeout" value="${serverValue}" />,然后在我的AJAX调用所在的外部文件中使用它。
$("#ajaxTimeout").val()

我今天进行了讨论,有人建议最好的做法是将仅供 JavaScript 使用的值存储在 HTML 的 <meta> 标签中。
这个重要吗?获取仅用于 JavaScript 的服务器端信息是否有首选方式?
我的理解是,如果隐藏输入字段不是表单的一部分,则可以安全地将其用于存储值,因为它不会附加到任何请求。话虽如此,我一直认为这确实有点像黑客行为。

你怎么想?

::编辑::
两个绝妙的答案:

4个回答

4

除了其他答案中提供的普通对象文字方法外,如果您想将要传递给客户端的值与特定的DOM元素相关(或者有一个表示该值所涉及的逻辑对象的DOM元素),则可以将该值放入数据属性中:

<div id="videoplayer" data-startplayingat="1:02">HTML Content</div>

这是一个完整属性,名为data-startplayingat,在现代浏览器中还有dataset属性。jQuery的语法是$('#videoplayer').data('startplayingat')

官方W3C关于数据属性的规范解释了所有这些。

以下是一些有趣的亮点:

  • 名称不能使用大写字母,必须与XML兼容。
  • dataset属性会将破折号转换为驼峰式,例如名称start-playing将变成startPlaying

对象字面量方法的一个潜在缺点(我喜欢并且自己也用过)是,如果你想要在.js文件中使用该对象,那么通常需要通过动态解析器运行静态JavaScript文件--这会导致潜在的小型(但仍然存在的)性能损失。将对象声明放入HTML文件中的<script>标签中可以解决这个问题,但是你可能需要处理脚本加载顺序问题。


太好了,我更喜欢这种方法。这表明我已经很久没有写过JSP/ASP/PHP的东西了... - ZenMaster
以 AJAX 超时值为例(或任何与特定 DOM 无关的值),是否仍然值得创建一个 div 并使用数据属性来存储该值,而不是使用对象字面量? - wild_nothing
@wild_nothing 我认为使用数据属性应该是与DOM元素至少在逻辑上相关的事物。我不想将它们用于一般的页面数据。对于像ajax超时这样的东西,对象字面量会是我的首选。我只是想给你一个完整的答案集... - ErikE
太好了。你们帮了我大忙!那我就将此视为一般规则了。 - wild_nothing

3
我们个人会这样做:
var options = {
    selector: '#divId',
    serverSideVariableHere: <%=AspNetProperty %>,
    anotherServerSideVariableHere: <%=AspNetPropertyTwo %>
}
var viewModel = new KnockoutViewModel(options);
ko.applyBindings(viewModel, $(options.selector)[0]);

这只是使用KnockOut JS的示例,但这个想法可以扩展到您选择使用的任何JavaScript库(或不使用)

然后我们将这些选项传递给使用它们的任何东西,例如Knockout ViewModels或其他。这样我们的JavaScript保持可测试性,并且我们可以将任何值传递给我们的测试。


我在 Backbone+Rails 后端也是这样做的。例如,为了获取有关 currentUser 的一些相关信息,我们在布局中执行以下操作:var window.AppName.currentUser = new AppName.Model.CurrentUser($.parseJSON(<%= dump current_user useful attributes in json %>)); - Enders
2
请注意,在 ASP 经典版或 Asp.Net 网站中,需要额外的操作才能通过 ASP 解析器运行 .js 文件,因此需要进行一些额外的设置。这可能会对性能产生潜在的影响(虽然可能很小)。 - ErikE
另一方面,没有任何阻止您将必要的对象声明放入<script>标签中的html文件中 - 但是您需要仔细考虑内容的加载顺序。 - ErikE

1
使用 meta 标签来实现除浏览器元信息之外的功能,在我看来同样是一种 hack。
我认为应该将 JavaScript 数据存储在 JavaScript 中,使用 JavaScript 对象字面量。

1
我强烈推荐在data-属性中使用JSON片段。这样可以将它们限定在相关的HTML元素范围内,避免污染Javascript全局命名空间或生成额外的代码以处理命名空间。与服务器端的JSON串行器配合使用,这可以最大程度地减少手动转义值的情况。
(此外,我对一般情况下带有内容的<script>标签有所保留。视图和逻辑分离等等。)

我不确定是否有代码片段,因为您需要使用eval来执行它们,但是data-属性肯定是一个好方法。 - ZenMaster
@ZenMaster - 非评估 JSON 解析是 JavaScript 1.7 的标准部分,并且在几乎任何您想要的浏览器上都可以使用:http://caniuse.com/#feat=json。(对于旧版本,您可以使用 Crockford 的 json2.js。) - millimoose
另一个微小的优势是,它将强制 jQuery 在 .data() 中执行自动类型转换时使用 JSON 解析,而不是进行其他可能不正确的猜测。 - millimoose
1
没错。最新项目上IE7的支持完全破坏了我的方法。顺便提一下,还有json3。 - ZenMaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接