ChatGPT解决这个技术问题 Extra ChatGPT

ReferenceError:未定义提取

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

ReferenceError:未定义提取

https://i.stack.imgur.com/3Syvz.png

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

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 选项,包括流、无数的身份验证方法等......

E
Endless

fetch API 未在 Node.js 中实现。

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

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

npm install node-fetch

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

import fetch from "node-fetch";

按照这些说明,我必须使用扩展名 .mjs 保存我的文件才能使其正常工作。
Node 中的 Fetch API has been implemented,应该发布 in a year or so
E
Endless

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

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

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

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

您可以使用 @lquixada 中的 cross-fetch

平台无关:浏览器、节点或 react native

安装

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 文档中有很好的解释。感谢分享
使用 crossfetch 的 polyfill 也适用于我使用 typescript 和 node 并从 amazon-cognito-identity-js 接收 ReferenceError: fetch is not defined 错误。
K
Khuram Niaz

如果你想避免 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);
})

请记住在此代码段的底部添加 .end() 以实际启动请求。请参阅docs
o
ofir_aghai

您应该在文件中添加此导入:

import * as fetch from 'node-fetch';

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

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


如果我以这种方式导入并使用 typescript,则会出现此错误 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 不支持这种现代导入语法。
T
Tomerikoo

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

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

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

npm i node-fetch --save

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

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

不支持 ES 模块的 require()
R
Rafael Lourenço

已编辑 - 新解决方案

要使用最新版本 (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”的错误。正如你所说,这个版本有漏洞,你应该总是使用最新的,所以我编辑了我的答案来解决这个问题。
在您的代码(新代码)中,Promise 将不起作用。如果您需要使用 require,请使用将获得关键更新的版本 2:“如果您无法切换到 ESM,请使用与 CommonJS 保持兼容的 v2。将继续为 v2 发布关键错误修复。” node-fetch@2
T
Tomerikoo

您必须将 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'; 以平滑测试环境的粗糙边缘。
k
krl

fetch 在实验标志 --experimental-fetch 下来到 Node v17

它将在没有标志的 Node v18 中可用。

https://github.com/nodejs/node/pull/41749#issue-1118239565

您不再需要安装任何其他软件包


节点 18 已发布,但仍处于试验阶段。
M
Mohammad Quanit

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


这在构建时发生得更多,虽然您的评论很好,但问题与您提出的不同
c
closedloop

对于那些也在 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'导入获取;相反是打字稿的一种修复
E
Expert Ngobeni

对于 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))

E
Endless

在 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();

n
nabais

在 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);
}

a
asma

这是相关的github issue 这个bug和2.0.0版本有关,升级到2.1.0版本就可以解决。您可以运行 npm i graphql-request@2.1.0-next.1


P
Pavel Muzik

以下在 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>
});

Y
YeonCheol Jang

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

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

V
Venryx

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

我知道的主要有:

节点获取

交叉获取

whatwg获取

同构提取

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


P
Piyush Aggarwal

这个答案不直接回答这个问题。相反,它建议另一种选择。

为什么?因为使用 'node-fetch' 变得越来越复杂,因为您无法使用 const fetch = require('node-fetch') 导入更新的版本。你必须做更多的事情才能让它发挥作用。

尝试使用 axios 包:

用于获取的简单安装 npm i axios 代码就像

const response = await axios.get(url).then(res => res.data)

R
Radim Šafrán

这对我有用:

const nodeFetch = require('node-fetch') as typeof fetch;

L
Lonely

解决方案 2022 年 7 月,节点版本 18.4.0

fetch 仍处于试验阶段,但我为您准备了一个分步指南。您不必额外安装任何东西。

第 1 步:假设我们想要获取多个 URL

我使用标准的开放 API(星球大战 API):

const starWarsPeople = [
  'https://swapi.dev/api/people/1/',
  'https://swapi.dev/api/people/2/',
  'https://swapi.dev/api/people/3/',
];

第 2 步:我们创建一个普通的自定义异步迭代器:

这不是必需的,但我们想这样做,因为这样每一步都在我们的控制之中:

starWarsPeople[Symbol.asyncIterator] = () => {
  let index = 0;

  return {
    async next() {
      if (index === starWarsPeople.length) {
        return { done: true };
      }

      const url = starWarsPeople[index];
      index++;
      const response = await fetch(url);

      if (!response.ok) {
        throw new Error('Cannot retrieve Url: ' + url);
      }

      return {
        value: await response.json(),
        done: false,
      };
    },
  };
};

第 3 步:我们使用 IIFE(立即调用函数表达式)

请注意最后一行中的 ()

(async function () {
  try {
    for await (const person of starWarsPeople) {
      console.log('Person: ', person?.name);
    }
  } catch (err) {
    console.error('Error: ', err);
  }
})();

最后但最不重要的:the whole example online (StackBlitz)

这是你的`tsconfig.json`

{
  "compilerOptions": {
    "target": "esnext",
    "lib": ["ESNext", "DOM"],
    "module": "esnext",
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipDefaultLibCheck": true,
    "skipLibCheck": true
  }
}

1
19_520 Karthikeya

只需将您的 app.js 文件扩展名设置为 app.mjs 即可解决问题!!!:)


J
JFM

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


您不得--save仅用于测试的内容。请改用 --save-dev
H
Henry Ecker

如果需要安装:

npm install --save global-fetch

然后

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

global-fetch 还是 node-fetch
正如目前所写的那样,您的答案尚不清楚。请edit添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以找到有关如何写出好答案的更多信息in the help center