在过去的几年里,我一直使用客户端隐藏的<input>
字段来存储服务器端值并在Javascript中使用它。
例如,假设我需要从应用配置中获取Ajax超时值。
我可能会在我的JSP中存储它:
<input type="hidden" id="ajaxTimeout" value="${serverValue}" />
然后使用它,就像我的AJAX调用存在于外部文件中一样:
$("#ajaxTimeout").val()
我今天正在讨论这个问题,并建议最好将值存储在HTML <meta>
代码中仅供Javascript使用的值。
这有关系吗?有没有一种首选方法来获取仅用于Javascript的服务器端信息?
我的理解是,如果隐藏的输入字段不是表单的一部分,那么用它来存储值是安全的,因为它不会附加到任何请求。话虽如此,我一直认为这确实是一个黑客攻击。
思考?
:: EDIT ::
两个很棒的答案:
答案 0 :(得分:4)
除了在其他答案中给出的普通旧对象文字方法之外,如果要传递给客户端的值是关于特定DOM元素(或者有一个DOM元素表示该值是关于的逻辑对象) ),您可以将值放在数据属性中:
<div id="videoplayer" data-startplayingat="1:02">HTML Content</div>
这可以作为整个属性data-startplayingat
访问,或者在现代浏览器中有dataset
属性。 jQuery语法是$('#videoplayer').data('startplayingat')
。
official W3C spec on data attributes解释了这一切。
以下是一些有趣的亮点:
dataset
属性会转换破折号,以使start-playing
之类的名称变为startPlaying
。对象文字方法(我喜欢并自己使用过)的一个潜在缺点是,如果你想在.js文件中使用该对象,那么通常必须通过动态解析器运行静态javascript文件 - 这将是导致潜在的小(但仍然存在)性能损失。将对象声明放入HTML文件中的<script>
标记可以解决此问题,但是您可以处理脚本加载顺序问题。
答案 1 :(得分: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仍然可以测试,我们可以将任何我们想要的值传递给我们的测试。
答案 2 :(得分:1)
将meta
标记用于浏览器元以外的其他内容 - “说明”不亚于黑客入侵IMO。
我会考虑使用JavaScript对象文字在JavaScript中存储JavaScript数据。
答案 3 :(得分:1)
我强烈更喜欢data-
属性中的JSON代码段。这使您可以将它们范围限定为相关的HTML元素,并且不会污染您的Javascript全局命名空间,或者必须生成额外的代码来处理命名空间。与服务器端的JSON序列化器配合使用,可以最大限度地减少手动转义值中的任何内容。
(另外我对<script>
标签有一个Thing™,内容一般。视图和逻辑分离等等。)