Node.js "btoa परिभाषित नहीं है" त्रुटि फेंकता है


230

अपने नोड.जेएस एप्लिकेशन में मैंने ऐसा किया npm install btoa-atobताकि मैं क्लाइंट साइड साइड जावास्क्रिप्ट में btoa () और atob () फ़ंक्शन का उपयोग कर सकूं लेकिन किसी कारणवश नोड में शामिल नहीं किया गया था। नई निर्देशिका ने मेरे नोड_मॉडल्स फ़ोल्डर में दिखाया, जो कि app.js. फिर मैंने अपने पैकेज में निर्भरता के रूप में btoa-atob को जोड़ना सुनिश्चित किया। जो फ़ाइल रूट में है।

हालांकि, किसी कारण से, यह अभी भी काम नहीं करेगा।

console.log(btoa("Hello World!"));

^ "SGVsbG8gV29ybGQh" को कंसोल में आउटपुट करना चाहिए, लेकिन इसके बजाय, मुझे त्रुटि "btoa परिभाषित नहीं है।"

क्या मैंने ठीक से इंस्टाल नहीं किया? मैंने क्या अनदेखी की?

जवाबों:


537

'Btoa-atob' मॉड्यूल प्रोग्रामेटिक इंटरफ़ेस निर्यात नहीं करता है, यह केवल कमांड लाइन उपयोगिताओं को प्रदान करता है।

यदि आपको Base64 में बदलने की आवश्यकता है तो आप बफर का उपयोग कर सकते हैं:

console.log(Buffer.from('Hello World!').toString('base64'));

उल्टा (जिस सामग्री को आप डिकोड कर रहे हैं वह utf8 स्ट्रिंग है):

console.log(Buffer.from(b64Encoded, 'base64').toString());

नोट: Node v4 से पहले, के new Bufferबजाय का उपयोग करें Buffer.from


57

यहां पोस्ट किए गए समाधान गैर-असिस्की पात्रों में काम नहीं करते हैं (अर्थात यदि आप Node.js और एक ब्राउज़र के बीच base64 का आदान-प्रदान करने की योजना बनाते हैं)। इसे काम करने के लिए आपको इनपुट टेक्स्ट को 'बाइनरी' के रूप में चिह्नित करना होगा।

Buffer.from('Hélló wórld!!', 'binary').toString('base64')

यह आपको देता है SOlsbPMgd/NybGQhIQ==। यदि आप atob('SOlsbPMgd/NybGQhIQ==')एक ब्राउज़र में बनाते हैं तो यह सही तरीके से डिकोड करेगा। यह इसे Node.js के माध्यम से भी सही करेगा:

Buffer.from('SOlsbPMgd/NybGQhIQ==', 'base64').toString('binary')

यदि आप "बाइनरी पार्ट" नहीं करते हैं, तो आप गलत तरीके से विशेष वर्णों को डिकोड करेंगे।

मुझे यह btoa npm पैकेज के कार्यान्वयन से मिला :


1
धन्यवाद, मैं बदल पात्रों के साथ पागल हो रहा था।
मैथ्यू जेम्स ब्रिग्स

1
धन्यवाद इवान, मैं इस में घंटे बिताएंगे ... आप का जवाब स्वीकार किया जाना चाहिए!
पावेल

इवान एलेग्रे बस 'बाइनरी' एन्कोडिंग का उपयोग न करें। यदि आप करते हैं Buffer.from('Hélló wórld!!').toString('base64')- यह आपको देगा SOlsbPMgd/NybGQhIQ==जो गैर-एससीआई स्ट्रिंग में ठीक से परिवर्तित किया जा सकता है।
TotalAMD

1
@TotalAMD यह Node.js से ब्राउज़र या वाइव्स से बेस 64 के आदान-प्रदान का काम नहीं करेगा
Iván Alegre

3
आप बेस 64 में एन्कोडिंग की तुलना कर रहे हैं और इसे एक ही प्लेटफॉर्म में डिकोड कर रहे हैं। क्रोम से क्रोम और नोड से नोड तक। यदि आप इसे बाइनरी 10 में बिना बाइनरी के एनकोड करते हैं, तो यह देगा SMOpbGzDsyB3w7NybGQhIQ==। यदि आप इसे एक ब्राउज़र में डिकोड करते हैं तो यह आपको देगा Hélló wórld!!। बाइनरी प्लेटफ़ॉर्म संगतता को सुनिश्चित करने के लिए सही है।
इवान एलेग्रे

22

रिएक्ट नेटिव और पाउचडीबी के साथ नोड का उपयोग करते समय मेरी टीम इस समस्या में भाग गई। यहां बताया गया है कि हमने इसे कैसे हल किया ...

एनपीएम बफर स्थापित करें:

$ npm install --save buffer

सुनिश्चित करें Buffer, btoaऔर atobएक ग्लोबल्स के रूप में भरी हुई हैं:

global.Buffer = global.Buffer || require('buffer').Buffer;

if (typeof btoa === 'undefined') {
  global.btoa = function (str) {
    return new Buffer(str, 'binary').toString('base64');
  };
}

if (typeof atob === 'undefined') {
  global.atob = function (b64Encoded) {
    return new Buffer(b64Encoded, 'base64').toString('binary');
  };
}

2
आपके कोड में कमांड नया बफ़र () नोड के नए संस्करणों में निम्न त्रुटि देता है: [DEP0005] डिप्रेवेशन वर्निंग: बफ़र () सुरक्षा और प्रयोज्य मुद्दों के कारण पदावनत है। इसके बजाय बफ़र .alloc (), बफ़र .allocUnsafe (), या बफ़र.फ्रॉम () विधियों का उपयोग करें।
रॉड्रिगो डे अल्मेडा सिकीरा

8

मैंने पाया कि यद्यपि ऊपर दिए गए उत्तरों से शिमर्स ने काम किया था, वे डेस्कटॉप ब्राउज़रों के कार्यान्वयन के व्यवहार से मेल नहीं खाते : btoa()औरatob()

const btoa = function(str){ return Buffer.from(str).toString('base64'); }
// returns "4pyT", yet in desktop Chrome would throw an error.
btoa('✓');
// returns "fsO1w6bCvA==", yet in desktop Chrome would return "fvXmvA=="
btoa(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));

जैसा कि यह पता चला है, Bufferउदाहरणों का प्रतिनिधित्व / व्याख्या UTF-8 में डिफ़ॉल्ट रूप से एन्कोड किए गए हैं । इसके विपरीत, डेस्कटॉप क्रोम में, आप एक स्ट्रिंग को भी इनपुट नहीं कर सकते हैं जिसमें लैटिन 1 के बाहर वर्ण होते हैं btoa(), क्योंकि यह एक अपवाद फेंक देगा:Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

इसलिए, आप स्पष्ट रूप से निर्धारित करने की आवश्यकता एन्कोडिंग प्रकार के लिए latin1डेस्कटॉप क्रोम का एन्कोडिंग प्रकार से मिलान करने के शिम अपने Node.js के लिए क्रम में:

const btoaLatin1 = function(str) { return Buffer.from(str, 'latin1').toString('base64'); }
const atobLatin1 = function(b64Encoded) {return Buffer.from(b64Encoded, 'base64').toString('latin1');}

const btoaUTF8 = function(str) { return Buffer.from(str, 'utf8').toString('base64'); }
const atobUTF8 = function(b64Encoded) {return Buffer.from(b64Encoded, 'base64').toString('utf8');}

btoaLatin1('✓'); // returns "Ew==" (would be preferable for it to throw error because this is undecodable)
atobLatin1(btoa('✓')); // returns "\u0019" (END OF MEDIUM)

btoaUTF8('✓'); // returns "4pyT"
atobUTF8(btoa('✓')); // returns "✓"

// returns "fvXmvA==", just like desktop Chrome
btoaLatin1(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));
// returns "fsO1w6bCvA=="
btoaUTF8(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));

नोड में v0.12.2 कोई बफ़र नहीं है। फारोम फ़ंक्शन
ज़िबरी

@Zibri Node v0.12.2 प्राचीन है और दो साल पहले जीवन के अंत तक पहुंच गया थाBuffer.from()है सिफारिश की जिस तरह से सुरक्षा कारणों से बफर एपीआई का उपयोग करने (हालांकि उस लिंक के लिए विकल्प स्पष्ट करेगी Buffer.from()कि नोड v0.12.2 लिए आवेदन कर सकते)।
जेमी बिर्च

मैं समझता हूं कि, लेकिन एक एम्बेडेड डिवाइस पर मेरे पास वह संस्करण है।
जिब्री

मैं एटम में अपना कोड स्क्रिप्ट पैकेज github.com/rgbkrk/atom-script का उपयोग करके चला रहा हूं जो नोड का पुराना कार्यान्वयन है। दूसरे शब्दों में, इसे btoa के लिए एक कार्यान्वयन की भी आवश्यकता है, जबकि यह Buffer.from () के साथ सामना नहीं कर सकता है।
शिरिम्पी

4

मेरे पास सर्वर और क्लाइंट के बीच एक कोड है और मुझे इसके अंदर btoa के कार्यान्वयन की आवश्यकता है। मैंने कुछ ऐसा करने की कोशिश की:

const btoaImplementation =  btoa || (str => Buffer.from(str).toString('base64'));

लेकिन सर्वर के साथ क्रश होगा:

ReferenceError: btoa परिभाषित नहीं है

जबकि Buffer ग्राहक पर परिभाषित नहीं किया गया है।

मैं window.btoa की जाँच नहीं कर सका (यह एक साझा कोड है, याद है?)

इसलिए मैंने इसे लागू किया:

const btoaImplementation = str => {
    try {
        return btoa(str);
    } catch(err) {
        return Buffer.from(str).toString('base64')
    }
};

1

मैं समझता हूं कि यह नोड एप्लिकेशन के लिए एक चर्चा बिंदु है, लेकिन एक नोड सर्वर पर चलने वाले सार्वभौमिक जावास्क्रिप्ट अनुप्रयोगों के हित में , इस तरह से मैं इस पोस्ट पर आया हूं, मैं एक सार्वभौमिक / आइसोमॉर्फिक रिएक्शन ऐप के लिए इस पर शोध कर रहा हूं। बिल्डिंग, और पैकेज ababने मेरे लिए काम किया। वास्तव में यह एकमात्र समाधान था जो मुझे मिल गया था, बफ़र पद्धति का उपयोग करने के बजाय भी उल्लेख किया गया था (मेरे पास टाइपस्क्रिप्ट मुद्दे थे)।

(यह पैकेज द्वारा उपयोग किया जाता है jsdom, जो बदले में windowपैकेज द्वारा उपयोग किया जाता है ।)

अपनी बात पर वापस आना; इसके आधार पर, शायद अगर यह कार्यक्षमता पहले से ही एक npm पैकेज के रूप में लिखी गई है, जैसा कि आपने उल्लेख किया है, और यह W3 कल्पना के आधार पर खुद का एल्गोरिथ्म है, तो आप इंस्टॉल और उपयोग कर सकते हैं।abab आप अपने स्वयं के फ़ंक्शन को लिखने के बजाय पैकेज कर सकते हैं जो हो सकता है या नहीं हो सकता है। एन्कोडिंग के आधार पर सटीक।

--- संपादित करें ---

मैं अजीब मुद्दों के साथ आज शुरू कर दिया कूटबन्धन (यकीन है कि यह अब क्यों शुरू हुआ है) पैकेज के साथ नहीं abab। यह ज्यादातर समय सही ढंग से एन्कोड करने के लिए लगता है, लेकिन कभी-कभी फ्रंट एंड पर यह गलत तरीके से एनकोड करता है। लंबे समय तक डिबग करने की कोशिश की, लेकिन पैकेज base-64की सिफारिश के अनुसार स्विच किया , और यह सीधे काम किया। निश्चित रूप से बेस64 एल्गोरिथ्म के लिए नीचे लग रहा था abab


1

एटम संपादक में 'स्क्रिप्ट' प्लगइन के साथ एक ही समस्या, जो कि नोड का पुराना संस्करण है, जिसमें न तो बोटो (), और न ही एटोब () है, और न ही यह बफ़र डेटाटाइप का समर्थन करता है। निम्नलिखित कोड चाल करता है:

var Base64 = new function() {
  var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
  this.encode = function(input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;
    input = Base64._utf8_encode(input);
    while (i < input.length) {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);
      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;
      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }
      output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
    }
    return output;
  }

  this.decode = function(input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    while (i < input.length) {
      enc1 = keyStr.indexOf(input.charAt(i++));
      enc2 = keyStr.indexOf(input.charAt(i++));
      enc3 = keyStr.indexOf(input.charAt(i++));
      enc4 = keyStr.indexOf(input.charAt(i++));
      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;
      output = output + String.fromCharCode(chr1);
      if (enc3 != 64) {
        output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
        output = output + String.fromCharCode(chr3);
      }
    }
    output = Base64._utf8_decode(output);
    return output;
  }

  this._utf8_encode = function(string) {
    string = string.replace(/\r\n/g, "\n");
    var utftext = "";
    for (var n = 0; n < string.length; n++) {
      var c = string.charCodeAt(n);
      if (c < 128) {
        utftext += String.fromCharCode(c);
      } else if ((c > 127) && (c < 2048)) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      } else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }
    }
    return utftext;
  }

  this._utf8_decode = function(utftext) {
    var string = "";
    var i = 0;
    var c = 0,
      c1 = 0,
      c2 = 0,
      c3 = 0;
    while (i < utftext.length) {
      c = utftext.charCodeAt(i);
      if (c < 128) {
        string += String.fromCharCode(c);
        i++;
      } else if ((c > 191) && (c < 224)) {
        c2 = utftext.charCodeAt(i + 1);
        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
      } else {
        c2 = utftext.charCodeAt(i + 1);
        c3 = utftext.charCodeAt(i + 2);
        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        i += 3;
      }
    }
    return string;
  }
}()

var btoa = Base64.encode;
var atob = Base64.decode;

console.log("btoa('A') = " + btoa('A'));
console.log("btoa('QQ==') = " + atob('QQ=='));
console.log("btoa('B') = " + btoa('B'));
console.log("btoa('Qg==') = " + atob('Qg=='));


यह धन्यवाद काम करता है। मेरे मामले में, मैं ChakraEngine का उपयोग कर रहा हूं जो अटोब का समर्थन नहीं करता है।
पानी

0

हो सकता है कि आपको इसकी आवश्यकता न हो, लेकिन यदि किसी को नोड का उपयोग करके इसकी आवश्यकता है: https://www.npmjs.com/package/btoa


0
export const universalBtoa = str => {
  try {
    return btoa(str);
  } catch (err) {
    return Buffer.from(str).toString('base64');
  }
};

export const universalAtob = b64Encoded => {
  try {
    return atob(b64Encoded);
  } catch (err) {
    return Buffer.from(b64Encoded, 'base64').toString();
  }
};

0

यहाँ बेस 64 एनकोडिंग के लिए एक संक्षिप्त सार्वभौमिक समाधान है:

const nodeBtoa = (b) => Buffer.from(b).toString('base64');
export const base64encode = typeof btoa !== 'undefined' ? btoa : nodeBtoa;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.