【问题标题】:Unable to access API key in Heroku Config Vars from Javascript app无法从 Javascript 应用程序访问 Heroku Config Vars 中的 API 密钥
【发布时间】:2020-12-12 01:43:37
【问题描述】:

我正在尝试将一个由 HTML、CSS 和 Javascript 文件组成的简单静态应用程序部署到 Heroku。我还添加了“虚拟”composer.json 和 index.php 文件,以允许静态文件驻留在 Heroku 中。当我转到托管页面时,我看到一个空白屏幕。控制台窗口如下所示。这些文件链接到我的 GitHub 存储库,因此我使用 .gitignore 文件排除我的 API 密钥,并将 API 密钥保存在 Heroku 的 Config Vars 中。应用未找到 API 密钥并引发错误。

Uncaught ReferenceError: MAPBOX_KEY is not defined                 logic.js:68
    at createMap (logic.js:68)
    at createFeatures (logic.js:56)
    at logic.js:9
    at d3.min.js:3
    at Object.<anonymous> (d3.min.js:7)
    at d.call (d3.min.js:4)
    at XMLHttpRequest.e (d3.min.js:7)

到目前为止,我已经尝试了以下方法:

  • 在设置/配置变量下直接在 Heroku 中添加 API 密钥

  • 使用控制台窗口添加密钥 heroku config:add MAPBOX_KEY=pk.eyJ1I.....

  • 禁用网页缓存

  • 在网页上运行空缓存并硬重新加载

  • 在控制台中运行 heroku 配置并收到以下错误:

    heroku config
    »   Error: Missing required flag:
    »     -a, --app APP  app to run command against
    »   See more help with --help
    

我已经搜索了文档和堆栈溢出,但在 Heroku 中找不到任何有关使用 Javascript 的 API 密钥的信息。我是否需要在我的 .js 或 .html 文件中添加额外的代码,以便应用程序在 Heroku 服务器上找到密钥?下面是 .js 代码的一部分,一直到错误所在的行。

// +++++ Leaflet Challenge +++++

// store API endpoint inside queryUrl
var queryUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson";

// make API call to USGS and perform a GET request to the query URL
d3.json(queryUrl, function(data) {
   // after a response, send the data.features object to the createFeatures function
   createFeatures(data.features);
});

// Circle radius function
function circleSize(magnitude) {
   return magnitude **2 * 2000 
};

// Circle color function by depth
function circleColor(depth) {
   switch (true) {
      case (depth > 90):
         return "#d73027"; //red
      case (depth > 70):
         return "#fc8d59"; //darkorange
      case (depth > 50):
         return "#fee08b"; //lightorange
      case (depth > 30):
         return "#d9ef8b"; //yellow
      case (depth > 10):
         return "#91cf60"; //yellowgreen
      default:
         return "#1a9850"; //green
   }
};

function createFeatures(earthquakeData) {

   // define a function and run once for each feature in the features array
   // give each feature a popup describing the place and time of the earthquake
   var earthquakes = L.geoJSON(earthquakeData, {
      onEachFeature: function(feature, layer) {
         layer.bindPopup("<h3>Magnitude: " + feature.properties.mag +"</h3><h3>Depth: " + feature.geometry.coordinates[2] + " km</h3><hr><h4>Location: " + feature.properties.place + "</h4><hr><p>" + new Date(feature.properties.time) + "</p>");
      },

      pointToLayer: function(feature, latlng) {
         return new L.circle(latlng, {
            radius: circleSize(feature.properties.mag),
            fillColor: circleColor(feature.geometry.coordinates[2]),
            color: "black",
            weight: .5,
            fillOpacity: 0.8
         })
      }
   });
  
   // send earthquakes layer to the createMap function
   createMap(earthquakes);
}

function createMap(earthquakes) {

   // define lightmap layer
   var lightmap = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
      attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
      tileSize: 512,
      maxZoom: 18,
      zoomOffset: -1,
      id: "mapbox/light-v10",  
      accessToken: MAPBOX_KEY
   });

提前感谢您提供的任何帮助。这是我第一次部署到 Heroku,所以对我来说是全新的。

【问题讨论】:

    标签: javascript api heroku config


    【解决方案1】:

    Heroku 配置变量是操作系统(linux、mac、windows)中的经典环境变量,旨在从可以访问操作系统的后端语言访问,例如:java、php、nodejs、ruby、python 等

    根据您的 sn-ps,您需要在您的 vanilla javascript 中读取此环境变量,该变量是从您的 html 在某些网络浏览器中调用的,这是不可能的

    在这种情况下,Vanilla javascript 或纯 javascript 不允许访问某些操作系统资源,例如环境变量。

    查看此链接以了解变量在 vanilla javascript 中的工作原理:

    How to use variable substitution in Frontend js applications like backend applications?

    快速解决方案

    在你的 php 代码中,在操作系统层的 web 渲染之前读取这个 var,因为 php 能够做到这一点:

    Php 不是我最好的技能,但我确信它有几个选项可以将此 var 注入静态 html 或 javascript

    如果没有,您可以在静态文件中使用简单的字符串替换:

    im_your_file.js

    zoomOffset: -1,
    id: "mapbox/light-v10",  
    accessToken: @@MAPBOX_KEY@@
    

    another_php_file.php

    replaceStringInFile("@@MAPBOX_KEY@@")
    

    脏溶液

    在另一个 php 文件中使用此替换文件中的内容,并在应用启动之前从一些 heroku 步骤调用它

    您可以使用纯 bash 执行此文件替换并在一些 heroku 步骤中调用它

    优雅的解决方案

    Webapck 变量注入

    最佳解决方案

    您必须在您的 php 应用程序中发布一种 rest 端点,例如 /settings.php,而不是直接读取 javascript 中的 var。此端点必须以 json 形式返回此变量和其他变量。

    在你的javascript文件中,而不是直接使用变量,使用/settings.php,你将在你的javascript代码中拥有所需的变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 2021-12-01
      相关资源
      最近更新 更多