You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在express-handlebars中访问客户端JavaScript声明的变量?

好问题!因为express-handlebars是服务端渲染的模板引擎,它的编译过程在服务器上完成,而客户端JS是在用户浏览器里运行的,两者处于完全不同的上下文环境,没法直接互相访问变量。不过根据你的需求场景,有几种实用的解决办法:

场景1:在客户端JS中访问服务端通过Handlebars传入的数据

这应该是你更常遇到的需求(毕竟你已经能从Express路由传数据到模板了)。核心思路是把服务端数据“注入”到客户端JS的上下文里:

  • 方法一:嵌入全局变量
    在你的Handlebars视图文件里,添加一个<script>标签,用JSON.stringify()把服务端数据转成合法的JS对象字面量,赋值给全局的window对象:
<!-- 假设你从路由传入了`user`对象,包含name和email字段 -->
<script>
  // 把服务端数据挂载到全局,客户端JS就能直接访问
  window.serverUser = {{JSON.stringify(user)}};
</script>

之后在任意客户端JS文件里,就可以直接调用serverUser.name或者serverUser.email了。

注意:JSON.stringify()会自动处理特殊字符的转义,避免出现JS语法错误,这比手动拼接字符串安全得多。

  • 方法二:存储到HTML的data属性
    如果只需要在特定DOM元素上使用服务端数据,可以把数据存在元素的data-*自定义属性里:
<!-- Handlebars模板中 -->
<button id="user-profile-btn" data-user="{{JSON.stringify(user)}}">查看我的资料</button>

<!-- 客户端JS中 -->
<script>
  const profileBtn = document.getElementById('user-profile-btn');
  // 解析data属性中的JSON字符串
  const user = JSON.parse(profileBtn.dataset.user);
  
  profileBtn.addEventListener('click', () => {
    alert(`你好,${user.name}!你的邮箱是${user.email}`);
  });
</script>

场景2:在Handlebars模板中访问客户端JS声明的变量

这里要明确:服务端编译Handlebars模板时,客户端JS还没有在浏览器中运行,所以没法直接在服务端渲染的Handlebars语法里引用客户端变量。你需要用客户端渲染的方式来实现:

  • 方法一:占位符替换
    先在Handlebars模板里预留一个占位元素,等客户端JS加载运行后,把变量值插入进去:
<!-- Handlebars模板中的占位符 -->
<div class="client-info">
  客户端变量值:<span id="client-var-placeholder">加载中...</span>
</div>

<!-- 客户端JS -->
<script>
  // 客户端声明的变量
  const myClientVariable = "这是我在浏览器里定义的变量";
  // 替换占位符内容
  document.getElementById('client-var-placeholder').textContent = myClientVariable;
</script>
  • 方法二:使用客户端版Handlebars
    如果需要用到Handlebars的模板语法(比如循环、条件判断)来渲染客户端数据,可以引入客户端版的Handlebars库,在浏览器中完成模板编译和渲染:
<!-- 引入客户端Handlebars库 -->
<script src="https://cdn.jsdelivr.net/npm/handlebars@4.7.7/dist/handlebars.min.js"></script>

<!-- 定义客户端模板(type设为text/x-handlebars-template避免浏览器解析) -->
<script id="client-template" type="text/x-handlebars-template">
  <h3>我的客户端列表</h3>
  <ul>
    {{#each clientItems}}
      <li>{{itemName}}</li>
    {{/each}}
  </ul>
</script>

<!-- 客户端JS -->
<script>
  // 客户端声明的变量
  const clientData = {
    clientItems: [
      { itemName: "待办事项1" },
      { itemName: "待办事项2" },
      { itemName: "待办事项3" }
    ]
  };

  // 编译模板并渲染到页面
  const template = Handlebars.compile(document.getElementById('client-template').innerHTML);
  const renderedContent = template(clientData);
  document.body.insertAdjacentHTML('beforeend', renderedContent);
</script>

内容的提问来源于stack exchange,提问作者apostrophedottilde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:20:23