【问题标题】:ReferenceError: fetch is not definedReferenceError:未定义提取
【发布时间】:2018-07-04 03:58:21
【问题描述】:

我在 node.js 中编译代码时出现此错误,我该如何解决?

ReferenceError: 未定义获取

这是我正在做的功能,它负责从特定的电影数据库中恢复信息。

function getMovieTitles(substr){  
  pageNumber=1;
  let url = 'https://jsonmock.hackerrank.com/api/movies/search/?Title=' + substr + "&page=" + pageNumber;
  fetch(url).then((resp) => resp.json()).then(function(data) {
    let movies = data.data;
    let totPages = data.total_pages;
    let sortArray = [];
    for(let i=0; i<movies.length;i++){
        sortArray.push(data.data[i].Title);
     }
    for(let i=2; i<=totPages; i++){
           let newPage = i;
           let url1 = 'https://jsonmock.hackerrank.com/api/movies/search/?Title=' + substr + "&page=" + newPage;

          fetch(url1).then(function(response) {
              var contentType = response.headers.get("content-type");
              if(contentType && contentType.indexOf("application/json") !== -1) {
                return response.json().then(function(json) {
                  //console.log(json); //uncomment this console.log to see the JSON data.

                 for(let i=0; i<json.data.length;i++){
                    sortArray.push(json.data[i].Title);
                 }

                 if(i==totPages)console.log(sortArray.sort());

                });
              } else {
                console.log("Oops, we haven't got JSON!");
              }
            });

        }
  })
  .catch(function(error) {
    console.log(error);
  });   
}

【问题讨论】:

  • 欢迎来到 SO,请提供您迄今为止尝试过的详细信息?请在需要时提供Minimal, Complete, and Verifiable example。也请花时间阅读How to Ask
  • fetch 不是标准的 nodejs 方法 - 你需要 node-fetch
  • fetch() 是为浏览器设计的,然后在您显然缺少的第三方模块中反向移植到 node.js。 request()request-promise() 库更原生地为 node.js 构建,并支持更广泛的 node.js 选项,包括流、无数的身份验证方法等......

标签: javascript node.js


【解决方案1】:

fetch API 没有在 Node 中实现。

您需要为此使用外部模块,例如 node-fetch

像这样在你的 Node 应用程序中安装它

npm install node-fetch

然后将下面的行放在您使用 fetch API 的文件的顶部:

import fetch from "node-fetch";

【讨论】:

  • 按照这些说明,我必须使用 .mjs 扩展名保存我的文件才能使其正常工作。
【解决方案2】:

这是一个快速的脏修复,请尝试在生产代码中消除这种用法。

如果fetch 必须可在全局范围内访问

import fetch from 'node-fetch'
globalThis.fetch = fetch

【讨论】:

  • 这是我能够让 WebStorm 识别 fetch 返回的承诺并自动完成可用方法的唯一方法。同意在生产中应该避免它,但对本地开发非常有帮助!
  • @FoxMulder900 这就是在没有全局定义的情况下仍然可以拥有 IntelliSense 的方式:const nodeFetch = require('node-fetch') as typeof fetch;
【解决方案3】:

您必须将isomorphic-fetch 模块用于您的Node 项目,因为Node 尚不包含Fetch API。要解决此问题,请运行以下命令:

npm install --save isomorphic-fetch es6-promise

安装后在您的项目中使用以下代码:

import "isomorphic-fetch"

【讨论】:

  • 没有积极维护;距离上次接受 PR 已经有好几年了。 github.com/matthew-andrews/isomorphic-fetch/graphs/contributors
  • 仅供参考,这可能会导致打字稿项目困难,因为该库不提供正确的类型。一个更简单的路由器是使用交叉获取,它非常相似,但与 typescript 配合得很好。对于您假设浏览器中可以正常获取的 React 应用程序,您可以将其设为开发依赖项并在测试设置中使用 import 'cross-fetch/polyfill'; 以平滑测试环境的粗糙边缘。
【解决方案4】:

你可以从@lquixada使用cross-fetch

平台无关:浏览器、节点或反应原生

安装

npm install --save cross-fetch

用法

承诺:

import fetch from 'cross-fetch';
// Or just: import 'cross-fetch/polyfill';

fetch('//api.github.com/users/lquixada')
  .then(res => {
    if (res.status >= 400) {
      throw new Error("Bad response from server");
    }
    return res.json();
  })
  .then(user => {
    console.log(user);
  })
  .catch(err => {
    console.error(err);
  });

使用异步/等待:

import fetch from 'cross-fetch';
// Or just: import 'cross-fetch/polyfill';

(async () => {
  try {
    const res = await fetch('//api.github.com/users/lquixada');

    if (res.status >= 400) {
      throw new Error("Bad response from server");
    }

    const user = await res.json();

    console.log(user);
  } catch (err) {
    console.error(err);
  }
})();

【讨论】:

  • 这有助于 metaweather api,在 github 文档中有很好的解释。感谢分享
【解决方案5】:

最好的一个是用于获取的 Axios 库。 使用npm i --save axios进行安装并像fetch一样使用它,只需编写axios而不是fetch,然后在then()中获得响应。

【讨论】:

  • 这在构建时发生得更多,虽然您的评论很好,但问题与您提出的不同
【解决方案6】:

对于那些也在 node-js 上使用 typescript 并收到 ReferenceError: fetch is not defined 错误的用户

npm install这些包:

    "amazon-cognito-identity-js": "3.0.11"
    "node-fetch": "^2.3.0"

然后包括:

import Global = NodeJS.Global;
export interface GlobalWithCognitoFix extends Global {
    fetch: any
}
declare const global: GlobalWithCognitoFix;
global.fetch = require('node-fetch');

【讨论】:

  • amazon-cognito-identity-js 与此问题无关,无需安装即可解决此错误。它也与打字稿无关。
  • 嗨!所以我遇到了完全相同的问题,但这仍然无法解决任何问题,您还有其他解决方法吗?
  • 我也在寻找解决方法。从'node-fetch'导入获取;相反是打字稿的一种修复
【解决方案7】:

Node.js 尚未实现 fetch() 方法,但您可以使用这个奇妙的 JavaScript 执行环境的外部模块之一。

在其他答案之一中,引用了“node-fetch”,这是一个不错的选择。

在您的项目文件夹(您拥有 .js 脚本的目录)中,使用以下命令安装该模块:

npm i node-fetch --save

然后将其用作要使用 Node.js 执行的脚本中的常量,如下所示:

const fetch = require("node-fetch");

【讨论】:

    【解决方案8】:

    这是相关的githubissue 该bug与2.0.0版本有关,升级到2.1.0版本即可解决。 你可以运行 npm i graphql-request@2.1.0-next.1

    【讨论】:

      【解决方案9】:

      以下在 Node.js 12.x 中适用于我:

      npm i node-fetch;
      

      初始化 Dropbox 实例:

      var Dropbox = require("dropbox").Dropbox;
      var dbx = new Dropbox({
         accessToken: <your access token>,
         fetch: require("node-fetch")    
      });
      

      例如上传内容(本例中使用的异步方法):

      await dbx.filesUpload({
        contents: <your content>,
        path: <file path>
      });
      

      【讨论】:

        【解决方案10】:

        你应该在你的文件中添加这个导入:

        import * as fetch from 'node-fetch';
        

        然后,运行此代码以添加 node-fetch:
        $ yarn add node-fetch

        如果您使用的是 typescript,请安装 node-fetch 类型:
        $ yarn add @types/node-fetch

        【讨论】:

        • 如果我以这种方式导入并使用打字稿,我有这个错误TS2349: This expression is not callable. Type 'typeof import("/node_modules/@types/node-fetch/index")' has no call signatures.。它仅适用于require
        • 运行$ yarn add @types/node-fetch 安装节点获取类型
        • 我当然做了,它是关于使用 es6 importrequire。似乎node-fetch 不支持这种现代导入语法。
        【解决方案11】:

        如果你想避免 npm install 不在浏览器中运行,你也可以使用 nodejs https 模块;

        const https = require('https')
        const url = "https://jsonmock.hackerrank.com/api/movies";
        https.get(url, res => {
          let data = '';
          res.on('data', chunk => {
            data += chunk;
          });
          res.on('end', () => {
            data = JSON.parse(data);
            console.log(data);
          })
        }).on('error', err => {
          console.log(err.message);
        })
        

        【讨论】:

        • 只记得在这个 sn-p 的底部添加.end() 以实际启动请求。见docs
        【解决方案12】:

        可能听起来很傻,但我只是在错误的项目中调用了npm i node-fetch --save。确保您在正确的目录中。

        【讨论】:

        • 您不能--save 仅用于测试的内容。请改用--save-dev
        【解决方案13】:

        对于 CORS 请求,似乎使用“http”或“https”获取支持 URL 方案。

        安装节点获取库npm install node-fetch,读取文件并解析为json。

        const fs = require('fs')
        const readJson = filename => {
          return new Promise((resolve, reject) => {
            if (filename.toLowerCase().endsWith(".json")) {
              fs.readFile(filename, (err, data) => {
                if (err) {
                  reject(err)
                  return
                }
                resolve(JSON.parse(data))
              })
            }
            else {
              reject(new Error("Invalid filetype, <*.json> required."))
              return
            }
          })
        }
        
        // usage
        const filename = "../data.json"
        readJson(filename).then(data => console.log(data)).catch(err => console.log(err.message))
        

        【讨论】:

          【解决方案14】:

          在 HackerRank 中,有些库是默认安装的,有些则没有。

          因为运行的是Node.js,默认不安装fetch API

          最好的办法是检查库是否已安装。

          在练习的顶部,有以下内容:

          const https = require('https');
          

          请尝试将此添加到顶部:

          const axios = require('axios');
          

          然后运行代码。

          如果出现编译错误,则不可用,否则可以使用axios,这是fetch的一个很好的替代品

          要将其与then 一起使用,您可以:

          function getMovieTitles(substr){
            axios.get(url)
              .then(function(response){
                console.log(response.data);
              })
          }
          

          或利用async/await

          async function getMovieTitles(substr){
            let response = await axios.get(url)
            console.log(response.data);
          }
          

          【讨论】:

            【解决方案15】:

            对我来说,这些看起来更简单。

            npm install node-fetch
            
            import fetch from "node-fetch";
            

            【讨论】:

              【解决方案16】:

              实际上有很多不同的库可以让fetch 在浏览器中可用。

              我知道的主要有:

              我目前使用 node-fetch,它运行良好,但我真的不知道哪个是“最好的”。 (尽管我链接的 openbase.com 页面提供了一些有关使用情况的元数据 [例如 Github 星标、npm 下载],这可以提供帮助)

              【讨论】:

                【解决方案17】:

                在 node.js 中你可以使用:node-fetch

                npm i node-fetch
                

                然后:

                import fetch from 'node-fetch';
                

                这是(nodejs)中的完整示例:

                import fetch from "node-fetch";
                
                const fetchData = async () => {
                  const res = await fetch("https://restcountries.eu/rest/v2/alpha/col"); // fetch() returns a promise, so we need to wait for it
                
                  const country = await res.json(); // res is now only an HTTP response, so we need to call res.json()
                
                  console.log(country); // Columbia's data will be logged to the dev console
                };
                
                fetchData();
                

                【讨论】:

                  【解决方案18】:

                  已编辑 - 新解决方案

                  要使用最新版本 (3.0.0),您必须像这样进行导入:

                  const fetch = (url) => import('node-fetch').then(({default: fetch}) => fetch(url));
                  


                  老答案:

                  可能不是最好的解决方案,但如果你安装这个版本:

                  npm install node-fetch@1.7.3
                  

                  您现在可以使用下面的行而不会出错。

                  const fetch = require("node-fetch");
                  

                  【讨论】:

                  • 是否有特定的理由使用这个旧版本而不是使用最新版本,特别是注意this vulnerability
                  • @LW001 当我遇到这个问题时,我做了一个快速修复。如果你使用新版本(3.0.0),它会在导入时出错,然后你会得到另一个说“fetch is not a function”的错误。正如你所说,这个版本有漏洞,你应该总是使用最新的,所以我编辑了我的答案来解决这个问题。
                  【解决方案19】:

                  只要把你的app.js文件扩展为app.mjs,问题就解决了!!!:)

                  【讨论】:

                    【解决方案20】:

                    如果需要安装:

                    npm install --save global-fetch
                    

                    然后

                    var fetch = require("node-fetch");
                    

                    【讨论】:

                    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                    • global-fetch 还是node-fetch
                    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
                    猜你喜欢
                    • 1970-01-01
                    • 2018-10-26
                    • 2021-08-07
                    • 2012-08-24
                    • 1970-01-01
                    • 2015-10-04
                    • 2017-04-10
                    相关资源
                    最近更新 更多