简体   繁体   English

在客户端将服务器端变量传递给 JavaScript 的最佳方法是什么?

[英]What is the best way to pass server side variables to JavaScript on the client side?

Our application uses a lot of configuration options.我们的应用程序使用了很多配置选项。 Those options need to be reflected on the client side in the form of User preferences, site wide preferences, etc.这些选项需要以用户首选项、站点范围首选项等的形式反映在客户端。

Currently, we pass server side settings down to the client side in the form of JSON that is stored in custom attributes in the markup for a specific element (and no, our application currently doesn't worry about W3C validation).目前,我们以 JSON 的形式将服务器端设置传递给客户端,该 JSON 存储在特定元素的标记中的自定义属性中(不,我们的应用程序目前不担心 W3C 验证)。 We then retrieve the data from the custom attribute, and parse it into a JSON object for use in script using jQuery.然后,我们从自定义属性中检索数据,并使用 jQuery 将其解析为 JSON 对象以在脚本中使用。

One drawback to this is referencing attributes on elements from within event handlers.这样做的一个缺点是从事件处理程序中引用元素上的属性。 I know this is frowned upon, as it can create circular references, and subsequently memory leaks.我知道这是不受欢迎的,因为它会创建循环引用,并随后导致内存泄漏。 I would much prefer to use jQuery's data function, but you can't invoke this from the server side at page render time.我更喜欢使用 jQuery 的 data 函数,但是您不能在页面呈现时从服务器端调用它。

What does everyone else do in this type of scenario?在这种情况下,其他人会怎么做?

Return the server data in JSON format.以 JSON 格式返回服务器数据。 You could do this through AJAX by returning a JSON header, or simple page outup and JSON.parse() .您可以通过 AJAX 返回 JSON 标头或简单的页面输出和JSON.parse()

You can assign the JSON data directly to an element's data.您可以将 JSON 数据直接分配给元素的数据。

$('#elementid').data('serverdata', data);

Update更新

After better understanding your situation I would suggest you use the data- attributes for three reasons.在更好地了解您的情况后,我建议您出于三个原因使用data-属性。

  1. You will have standards compliant markup.您将拥有符合标准的标记。
  2. The recent version of jQuery relies on these for the .data function.最新版本的 jQuery 依赖于这些.data函数。
  3. The change will require little modification to your current application (changing the way custom attributes are output from customAtt="value" to data-customAtt="value"此更改几乎不需要对您当前的应用程序进行修改(将自定义属性的输出方式从customAtt="value"更改为data-customAtt="value"

Here is some more information on the data attributes.以下是有关数据属性的更多信息。

You can render in the page an inline script that defines a JS object with all the preferences.您可以在页面中呈现一个内联脚本,该脚本定义了一个具有所有首选项的 JS 对象。 This way, your scripts have access to the data the moment the browser is done with the page load.这样,您的脚本就可以在浏览器完成页面加载时访问数据。 The drawbacks:缺点:

  • you have inline script in the page, which some people frown upon;您在页面中有内联脚本,有些人对此不屑一顾;
  • caching the page might result in oder preferences being used for particular page instance;缓存页面可能会导致特定页面实例使用更多首选项;
  • each page size is increased with the prefs size.每个页面大小都随着首选项大小而增加。

Or you can render in the page a link to an external script that declares the preferences.或者,您可以在页面中呈现一个指向声明首选项的外部脚本的链接。 This way, the preferences don't block the page rendering, and can be cached separately by the browser.这样,首选项不会阻止页面渲染,并且可以由浏览器单独缓存。 Drawbacks:缺点:

  • the page might render with older preferences and then get update to the new preferences, which on slower networks might be visible;页面可能会使用旧的首选项呈现,然后更新到新的首选项,这在较慢的网络上可能是可见的;

Or you could directly add the data to an element using the HTML5 data attributes (thus being HTML5 conformant and jQuery.Data compatible, as it uses those as well).或者您可以使用 HTML5 数据属性直接将数据添加到元素(因此符合 HTML5 和 jQuery.Data 兼容,因为它也使用这些属性)。 Drawback:缺点:

  • you lose IE support;你失去了 IE 支持;

At my projects I usually render such data as global JavaScript variables at the top of master page:在我的项目中,我通常将这些数据作为全局 JavaScript 变量呈现在母版页的顶部:

<script language="javascript">
var g_someOption=<%= Options.SomeOption.SerializeToJsonLiteral() %>;
var g_someOtherOption=<%= Options.SomeOtherOption.SerializeToJsonLiteral() %>;
// or
var g_globalOptions = {
    thirdOption:<%= Options.ThirdOption.SerializeToJsonLiteral() %>,
    foursOption:<%= Options.FourthOption.SerializeToJsonLiteral() %>
};
// or even via special helper that renders object above
<%= Html.RenderGlobalScriptVars() %>
</script>

If project is full of AJAX and user can stay on some page for a long time, it is possible to refresh settings periodically using AJAX requests to the server.如果项目中充满了 AJAX 并且用户可以长时间停留在某个页面上,则可以使用 AJAX 向服务器请求定期刷新设置。

PS I've used aspx syntax, but I believe that you got an idea even if you're using some other language. PS 我使用过 aspx 语法,但我相信即使您使用其他语言,您也会有一个想法。

Just to add another option, you can always do a只是为了添加另一个选项,您可以随时执行

<script type="text/javascript" src="settings.php"></script>

to output stuff from PHP.从 PHP 输出东西。 You can use this to invoke the necessary data calls, for example.例如,您可以使用它来调用必要的数据调用。 Just send the correct header.只需发送正确的标题。

I usually use MVC, so I'm in the habit of making AJAX calls when the page loads to get objects I might need.我通常使用 MVC,所以我习惯于在页面加载时进行 AJAX 调用以获取我可能需要的对象。 I'm not sure what technology you're using, but it shouldn't be too hard to set up an endpoint that returns this JSON and call it when the DOM is ready.我不确定您使用的是什么技术,但是设置一个返回此 JSON 并在 DOM 准备就绪时调用它的端点应该不会太难。 Then you can store it as a JavaScript variable and not worry about stuffing it into some element's attributes.然后你可以将它存储为一个 JavaScript 变量,而不必担心将它填充到某些元素的属性中。

A good compromise is to render a single configuration object that is keyed by the ids you use for the nodes (or any other scheme that will let your handlers find the data).一个很好的折衷方案是呈现一个配置对象,该对象由您用于节点的 id(或任何其他可以让您的处理程序找到数据的方案)键控。 Instead of using inline handlers, set the handlers after the page is loaded.不要使用内联处理程序,而是在页面加载后设置处理程序。 Then it should be easy to reference the json your server side created.然后应该很容易引用您的服务器端创建的 json。

This example uses semi-globals此示例使用半全局变量

<script>
$(function() {
  // The following line would be generated in php using something like:
  // var cfg = <?= json_encode($cfg) ?>; 
  var cfg = {
     orders: [{total: 25, itemCount: 10}], 
     waiting: [{total: 20, reason: "Out of strock"}]
  };
  $('orders').click(function(){
    alert('You have a total of ' +  cfg.orders[0].itemCount + 'orders');
  });
})
</script>

<body>
<div id='orders'> Here are your orders</div>
</body>

Alternatively if you really want to scope your variables, you can do the following:或者,如果您真的想限定变量的范围,您可以执行以下操作:

<script>
$(function() {
  $('orders').click(function(){
    var orders = <?= json_encode($orders) ?>; 
    alert('You have a total of ' +  orders[0].itemCount + 'orders');
  });
})
</script>

<body>
<div id='orders'> Here are your orders</div>
</body>

The above example is less flexible since you couldn't reuse the orders variable from other handlers if you needed to.上面的示例不太灵活,因为如果需要,您无法重用来自其他处理程序的 orders 变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将客户端 javascript 时钟与服务器日期同步的最佳方式 - The best way to synchronize client-side javascript clock with server date 将许多服务器端信息传递给JavaScript的最佳实践是什么? - What is the best practice to pass many server side information to JavaScript? 处理存储为javascript变量的服务器端数据的最佳方法是什么 - What is the best way to deal with server side data saved as a javascript variable Asp.net。 服务器端验证和客户端验证很好地协同工作的最佳方式是什么 - Asp.net. what’s the best way that server side validation and client side validation work together nicely 客户端的 Typescript 模块 - 最好的方法是什么? - Typescript modules in client side - What is the best way? 验证客户端JavaScript事件的最佳方法 - Best way to authenticate client side JavaScript events 使用nodejs + express处理服务器端和客户端错误的最佳方法是什么 - What's the best way to deal with an error in the server side and in the client side using nodejs + express 什么是客户端javascript,什么是服务器javascript? - What is client side javascript and what is server side javascript? 客户端javascript或服务器端 - client side javascript or server side 将客户端JavaScript变量传递给服务器端php - Pass client-side javascript variable to server-side php
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM