首页 > 解决方案 > EmberJS:在 index.html 中设置环境变量

问题描述

我们有一个 Ember (3.5) 应用程序。出于技术原因,我们需要在页面加载时设置环境变量,而不是构建时间。我们正在尝试index.html通过以下方式设置它们:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>App</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {{content-for "head"}}
    <script type="application/javascript">
      // Object.assign polyfill
      Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
      window.env = {};

      var request = new XMLHttpRequest();
      request.open('GET', '/api/frontend_settings', true);
      request.send(null);

      request.addEventListener('readystatechange', () => {
        if (request.status === 200) {
          if (request.readyState === 4) {
            Object.assign(window.env, JSON.parse(request.response).settings);
          }
        }
      }, false);
    </script>

    <link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
    <link integrity="" rel="stylesheet" href="{{rootURL}}assets/app-frontend.css">

    {{content-for "head-footer"}}
  </head>
  <body>
    <script integrity="" src="{{rootURL}}assets/vendor.js"></script>
    <script integrity="" src="{{rootURL}}assets/app-frontend.js"></script>
  </body>
</html>

/api/frontend_env_vars我们添加了一个脚本,该脚本向片段中的某个端点 ( ) 发出请求。该端点使用带有环境变量键值的 JSON 进行响应,然后我们将其分配给window.env.

我们遇到的问题是,有时 Ember 脚本会在分配变量之前加载(因为我们执行的请求需要一些时间才能完成),这会使应用程序崩溃。

我们尝试对脚本进行以下更改,但没有成功(但错误有所不同):

<script type="application/javascript">
  // Object.assign polyfill
  Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
  window.env = {};
  var request = new XMLHttpRequest();
  request.open('GET', '/api/frontend_env_vars', true);
  request.send(null);
  function loadScript(src) {
    const script = document.createElement('script');
    script.src = src;
    document.body.append(script);
  }
  request.addEventListener('readystatechange', () => {
    if (request.status === 200) {
      if (request.readyState === 4) {
        Object.assign(window.env, JSON.parse(request.response).settings);
        loadScript('assets/vendor.js');
        loadScript('assets/app-frontend.js');
      }
    }
  }, false);
</script>

标签: javascriptember.js

解决方案


我们使用ember-cli-server-variables完成此操作

它允许您在index.html

<html>
  <head>
    <meta name='your-app-token' content='example:app:token'>
    <meta name='your-app-user-location' content='Denver'>
    <meta name='your-app-json-data' content='{"foo":"bar"}'>
  </head>
</html>

然后从应用程序访问它们。

index.html 我们使用所需的变量在服务器上构建我们的,不需要异步来获取它们。


推荐阅读