ReferenceError:未定义提取

Posted

技术标签:

【中文标题】ReferenceError:未定义提取【英文标题】:ReferenceError: fetch is not defined 【发布时间】: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 选项,包括流、无数的身份验证方法等...... 【参考方案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 cross-fetch whatwg-fetch isomorphic-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。

以上是关于ReferenceError:未定义提取的主要内容,如果未能解决你的问题,请参考以下文章

获取 ReferenceError:未定义提取

app.js:81010 [Vue 警告]:挂载钩子错误:“ReferenceError: $store 未定义”

ReferenceError:数据未在exports.action中定义

未定义函数 - 未捕获的 ReferenceError

打字稿 - 未捕获的 ReferenceError:未定义导出

ReferenceError: $ 未定义