جاوااسکریپت - خطای مرجع: تابع fetch تعریف نشده است


وقتی کد خود را در node.js کامپایل میکنم، این خطا را دارم، چگونه میتوانم آن را رفع کنم؟

ReferenceError: fetch تعریف نشده است

این تابعی است که من انجام میدهم، مسئول بازیابی اطلاعات از یک پایگاه داده فیلم خاص است.

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

پاسخ شماره ۱

اگر از نسخهای از Node قبل از ۱۸ استفاده میکنید، API fetch بهصورت پیشفرض پیادهسازی نشده است و نیاز دارید از یک ماژول خارجی برای آن استفاده کنید، مانند node-fetch.

آن را در برنامه Node خود به این صورت نصب کنید

npm install node-fetch

سپس خط زیر را در بالای فایلهایی که از API دریافت استفاده میکنید قرار دهید:

import fetch from "node-fetch";

اگر برنامه شما نمیتواند بهروزرسانی شود تا از ESM (یا همان نحو import) استفاده کند، و شما نیاز دارید از CommonJS (یا همان require) استفاده کنید، پس با نسخه ۲ node-fetch ادامه دهید. طبق README آنها، نسخه ۲ به دریافت اصلاحات حیاتی باگ ادامه خواهد داد.

npm install node-fetch@2

و سپس این کار خواهد کرد,

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

پاسخ شماره ۲

این یک رفع سریع و موقتی است، لطفاً سعی کنید از استفاده از این در کد تولیدی خودداری کنید.

اگر fetch باید در دسترس با دامنه سراسری باشد

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

پاسخ شماره ۳

شما میتوانید از cross-fetch از @lquixada استفاده کنید

بیتعلق به پلتفرم: مرورگرها، نود یا ریاکت نیتیو

نصب

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

با async/await:

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

پاسخ شماره ۴

اگر میخواهید از اجرای دستور npm install و اجرا نشدن در مرورگر جلوگیری کنید، میتوانید از ماژول https در nodejs نیز استفاده کنید؛

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

با شروع نسخه 18 نود، Fetch API در دسترس است (در نسخه 21.x پایدار است) https://nodejs.org/docs/latest-v21.x/api/globals.html#fetch

// Promise version:

const url = "https://jsonmock.hackerrank.com/api/movies";

fetch(url).then(res => {
    return res.json();
}).then(data => {
    console.log('DATA: ', data);
})

یا

// async/await version

const url = "https://jsonmock.hackerrank.com/api/movies";

const getData = async () => {
    const response = await fetch(url);

    if (response.ok) {
        const data = await response.json();

        console.log('DATA: ', data);
    }
};
getData();

پاسخ شماره ۵

fetch در نسخه ۱۷ نود تحت پرچم آزمایشی --experimental-fetch معرفی شد

این در نسخه Node v18 بدون نیاز به فلگ در دسترس خواهد بود.

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

شما دیگر نیازی به نصب هیچ بسته اضافی ندارید

پاسخ شماره ۶

ویرایش شده - راه حل جدید

برای استفاده از آخرین نسخه (3.0.0) باید ایمپورت را به این صورت انجام دهید:

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


پاسخ قدیمی:

این ممکن است بهترین راهحل نباشد، اما اگر این نسخه را نصب کنید :

npm install [email 

شما اکنون میتوانید از خط زیر بدون خطاها استفاده کنید.

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

پاسخ شماره ۷

Node.js متد fetch() را پیادهسازی نکرده است، اما میتوانید از یکی از ماژولهای خارجی این محیط اجرای فوقالعاده برای جاوااسکریپت استفاده کنید.

در یکی از پاسخهای دیگر، «node-fetch» ذکر شده و این یک انتخاب خوب است.

در پوشه پروژه خود (دایرکتوری که اسکریپتهای .js را در آن دارید) آن ماژول را با فرمان زیر نصب کنید:

npm i node-fetch --save

سپس از آن به عنوان یک ثابت در اسکریپتی که میخواهید با Node.js اجرا کنید، استفاده کنید، چیزی شبیه به این:

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

پاسخ شماره ۸

شما باید این واردسازی را در فایل خود اضافه کنید:

import * as fetch from 'node-fetch';

و سپس، این کد را اجرا کنید تا node-fetch را اضافه کنید:
$ yarn add node-fetch

اگر با TypeScript کار میکنید، سپس تایپها برای node-fetch را نصب کنید:
$yarn add @types/node-fetch