nextjs 中的环境变量

ill*_*ria 4 reactjs next.js

我真的一直在尝试了解如何在 nextjs 中处理环境变量,但我仍然不明白。我只是想从下面的代码中隐藏我的 API 密钥。据我了解,我只能通过使用 getServerSideProps 或 getStaticProps 来做到这一点。如果是这样的话,尽管我仍然不知道应该如何相应地修改我的代码

       import { createContext, useState, useEffect } from 'react';

const WeatherContext = createContext({
  searchLocation: (input) => {},
  btnHandler: (input) => {},
  weather: '',
  isLoading: true,
});

export function WeatherContextProvider(props) {
  const [weather, setWeather] = useState({});
  const [city, setCity] = useState('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const [unit, setUnit] = useState('metric');
  const [searchInput, setSearchInput] = useState('');
  

  const btnHandler = () => {
    if (unit === 'metric') {
      setUnit('imperial');
    } else {
      setUnit('metric');
    }
  };

  const searchLocation = async (input = searchInput, units = unit) => {
    if (loading) {
      input = 'London';
    }
    try {
      const firstResponse = await fetch(
        `https://api.openweathermap.org/data/2.5/weather?q=${input}&units=${units}&appid=KEY`
      );
      
      const firstData = await firstResponse.json();
      if (!firstResponse.ok) {
        setError(true);
        throw new Error('Something went wrong');
      }

      let lon = firstData.coord.lon;
      let lat = firstData.coord.lat;

      const response = await fetch(
        `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&units=${units}&exclude=&appid=KEY`
      );
      const data = await response.json();

      if (!response.ok) {
        setError(true);
        throw new Error('Something went wrong');
      }
      setWeather(data);
      setCity(firstData.name + ', ' + firstData.sys.country);
      setSearchInput(firstData.name);
      setLoading(false);
      setError(false);
    } catch (error) {
      setError(error.message);
      console.log(error);
    }
  };

  useEffect(() => {
    searchLocation();
  }, [unit, searchInput]);

  const context = {
    searchLocation: searchLocation,
    city: city,
    weather: weather,
    isLoading: loading,
    error: error,
    btnHandler: btnHandler,
    unit: unit,
    searchInput: searchInput,
  };

  return (
    <WeatherContext.Provider value={context}>
      {props.children}
    </WeatherContext.Provider>
  );
}

export default WeatherContext;
Run Code Online (Sandbox Code Playgroud)

小智 6

不幸的是,如果您希望从客户端访问 api,那么您将公开 env 变量,而从 getServerSideProps 或 getStaticProps 进行的任何调用都可以使 env 变量在服务器端保持私有。

同样重要的是要记住,当创建将在 React 代码中在客户端公开/访问的 env 变量时,您需要在 env 变量名称前面加上NEXT_PUBLIC_,这样 nextjs 就知道允许 env 变量在客户端。

话虽如此,处理 api 密钥情况的最佳方法似乎是在项目的根目录下创建一个 .env 文件并添加类似NEXT_PUBLIC_API_KEY=insert-your-api-key-here.

如果您绝对需要保持此 api 密钥的私密性,我认为您最好的做法是在页面文件夹 (/pages/[slug].jsx) 中创建动态路由,并在该页面的 getServerSideProps 中创建一个动态路由,您可以使用参数数据在服务器端进行 api 调用,这将使您的 api 密钥包含在服务器端。