简体   繁体   English

节点process.env变量为空

[英]Node process.env variables empty

I'm building my first Express app, which needs to interact with an API, using an API key that ideally remains secure. 我正在构建我的第一个Express应用程序,它需要使用理想情况下仍然安全的API密钥与API进行交互。

So I wanted to follow a basic pattern of keeping the key (and any future environment variables), in a .gitignore d .env file in the root directory. 所以我想在根目录中的.gitignore d .env文件中遵循保持密钥(以及任何未来的环境变量)的基本模式。

To not reinvent the wheel, I used this package , and set my env variables like so, in my app.coffee file (the root file of the application): 为了不重新发明轮子,我使用了这个包 ,并在我的app.coffee文件(应用程序的根文件)中设置了我的env变量:

env = require('node-env-file')
env __dirname + '/.env'
console.log process.env.MY_API_KEY

That console.log prints out the right key to the server logs. console.log打印出服务器日志的正确密钥。 The problem arises later: 问题出现了:

If I try to access that same variable in one of the JS files loaded later on by my app, process.env is an empty object, so the API key is undefined . 如果我尝试在我的应用程序稍后加载的一个JS文件中访问该相同的变量,则process.env是一个空对象,因此API键undefined This doesn't appear to be a problem with the above package, because if I define the variable in the CL ( API_KEY=whatever npm start ), the behavior is the same -- it console logs correctly from app.coffee but is unavailable later. 似乎不符合上述包装有问题,因为如果我在CL(定义变量API_KEY=whatever npm start ),该行为是相同的-从正确的控制台日志app.coffee但不可用后。

Some information on how the files in which the key is unavailable are being loaded: 有关如何加载密钥不可用的文件的一些信息:

  • The app is running React, which I write to a few .jsx files in public/javascripts/src , and which are compiled by gulp into public/javascripts/build/*.js . 该应用程序运行反应,这是我写了几.jsx文件在public/javascripts/src ,并且由编译gulppublic/javascripts/build/*.js
  • I'm trying to access the key in a .js file in public/javascripts/ which is require d by one of the .jsx files. 我正在尝试访问public/javascripts/中的.js文件中的密钥,这require其中一个.jsx文件。
  • In that required .js file, process.env returns an empty object. 在该必需的.js文件中, process.env返回一个空对象。 When I try to access process.env in the .jsx files, I'm actually told that process itself is undefined. 当我尝试访问process.env.jsx文件,实际上,我告诉process本身是不确定的。

Any ideas what's going on here? 有什么想法在这里发生了什么? I'm new to Express/React, and unclear where this process object, which I thought was global and defined on npm start is defined, and what's happening to all the env info in it. 我是Express / React的新手,并且不清楚这个process对象在哪里被定义为全局并且在npm start上定义,以及其中所有env信息发生了什么。

Thanks! 谢谢! Please let me know if any other information would be helpful, orif anyone has any suggestions for how better to handle private env info in my situation. 请让我知道如果任何其他信息将是有益的,切开复位内固定任何人有如何更好地处理私人任何建议env在我的情况的信息。

EDIT : 编辑

I tried the suggestions below, and created a separate endpoint internally, which hits the external API and then returns a response. 我尝试了下面的建议,并在内部创建了一个单独的端点,它点击外部API然后返回响应。 I've strung things up correctly, so that this responds correctly: 我已经把事情做好了,所以这才能正确回应:

router.get '/images', (req, res, next) ->
  res.json({ some: 'json' });

but this (which uses a separate class to make a request to an external API), throws an error: 但是这个 (它使用一个单独的类来向外部API发出请求)会抛出一个错误:

router.get '/images', (req, res, next) ->
  new Images('nature').fetch (images) ->
    res.json({ some: 'json' })

Essentially, it looks like the asynchrony of the response from the external API (and not even the data itself, which I ignored), is creating a problem. 从本质上讲,它看起来像外部API的响应的异步(甚至不是数据本身,我忽略了),正在创建一个问题。 How do I hit this external endpoint and then respond to the internal request with the incoming data? 如何点击此外部端点,然后使用传入数据响应内部请求?

All .jsx is, is some code, what matters is where the code is being executed. 所有.jsx都是一些代码,重要的是代码执行的地方。 process.env is a variable that is accessible inside the Node.js runtime. process.env是一个可在Node.js运行时内访问的变量。 When your .jsx code gets transpiled down to .js and served to the browser, the process.env variable will no longer exist. 当.jsx代码被编译为.js并提供给浏览器时, process.env变量将不再存在。 If you're making an API call inside the browser, the API key will be fundamentally available to the client. 如果您在浏览器中进行API调用,则API密钥将从根本上提供给客户端。 If you want to secure the key, you have to have your Node.js server expose an API route, which your React app will hit. 如果要保护密钥,则必须让Node.js服务器公开您的React应用程序将会遇到的API路由。 That Node.js server will then make the call to the external service using the API key. 然后,Node.js服务器将使用API​​密钥调用外部服务。 Because that call is being made by the server, process.env will be available, and will remain hidden from the client. 由于该调用是由服务器进行的,因此process.env将可用,并将保持对客户端的隐藏。 You can then forward the result of the API call back to the user. 然后,您可以将API调用的结果转发回用户。

Back-end vs Front-end 后端vs前端

It seems like you are trying to access back-end data from a front-end location, in a wrong way. 您似乎正试图以错误的方式从前端位置访问后端数据。 The great power of Node.js is having JavaScript in the front and in the back, but it is quite confusing in the beginning to understand on which side each script is executed. Node.js的强大功能是在前面和后面都有JavaScript,但是在开始时要理解每个脚本执行的哪一方是非常混乱的。

In an Express project, all Javascript files that are sent to the front-end, those that will directly interact with the client's page, are located in public/javascripts/ . 在Express项目中,发送到前端的所有Javascript文件(即将直接与客户端页面交互的文件)都位于public/javascripts/ Generally you will have some AJAX functions in some of those files to exchange data and communicate with the back-end. 通常,您将在某些文件中使用一些AJAX函数来交换数据并与后端进行通信。

These back-end files are located everywhere else : in the root directory, in routes/ , and all the other folders you create. 这些后端文件位于其他任何位置:根目录, routes/以及您创建的所有其他文件夹。 Those files are pretty much all connected to your Node instance, and therefore can communicate with each other using global objects like process for example. 这些文件几乎全部连接到您的Node实例,因此可以使用全局对象(例如process相互通信。

Your script in public/javascripts/ , that is executed on the client's computer, is trying to directly access a variable located on the server running your Node instance : that's why your code doesn't work. 您在客户端计算机上执行的public/javascripts/脚本正在尝试直接访问运行Node实例的服务器上的变量:这就是您的代码不起作用的原因。 If you wish to access data from the back-end, you must use AJAX calls in the front-end. 如果要从后端访问数据,则必须在前端使用AJAX调用。

Server   <---(AJAX only)---   Client
------                        ------
app.js                        public/javascripts/script.js
routes.js
...

That being said, you wanted to keep your API key private, which will not happen if you send it to every client who's on that specific page. 话虽如此,您希望将API密钥保密,如果将其发送给该特定页面上的每个客户端,则不会发生这种情况。 What you should do is make the call from the back-end, using the xhr module for example, and then delivering the data to front-end, without the secret API key. 您应该做的是使用xhr模块从后端进行调用,然后将数据传递到前端,而不使用秘密API密钥。

I hope I was clear, Node is quite confusing at first but very soon you will get over these little mistakes ! 我希望我很清楚,Node一开始很混乱,但很快你就会克服这些小错误!

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM