2014-04-16 15 views
84

Trong ứng dụng Node.js của tôi, tôi đã làm một npm install btoa-atob vì vậy mà tôi có thể sử dụng btoa() và atob() chức năng mà có nguồn gốc ở client-side javascript nhưng vì một lý do không được bao gồm trong nút. Thư mục mới xuất hiện trong thư mục node_modules của tôi, thư mục này nằm trong thư mục gốc cùng với app.js. Sau đó, tôi chắc chắn để thêm btoa-atob như là một phụ thuộc trong tập tin package.json của tôi mà là ở gốc.Node.js - "btoa không được định nghĩa" lỗi

Tuy nhiên, vì lý do nào đó, nó vẫn không hoạt động. sản lượng

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

^nên "SGVsbG8gV29ybGQh" vào giao diện điều khiển, nhưng thay vào đó tôi nhận được lỗi "btoa không defiend."

Tôi không cài đặt đúng cách? Tôi đã bỏ qua điều gì?

Trả lời

184

Mô-đun 'btoa-atob' không xuất giao diện có lập trình, nó chỉ cung cấp các tiện ích dòng lệnh.

Nếu bạn cần chuyển đổi sang Base64 bạn có thể làm như vậy bằng Buffer:

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

Xếp (giả định các nội dung mà bạn đang giải mã được một chuỗi utf8):

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

Lưu ý: trước Node v4, hãy sử dụng new Buffer thay vì Buffer.from.

+0

Cảm ơn! – Joey

+17

Nếu nó giúp một ai đó, tôi đặt nó trong mocha common.js: '' 'global.btoa = function (str) {return new Buffer (str) .toString ('base64');};' '' để tôi có thể kiểm tra trong bảng điều khiển như thể tôi đã có trình duyệt. – snapfractalpop

+3

Tuy nhiên, một khác biệt nhỏ giữa node.js và trình duyệt làm cho nó khó khăn hơn một chút để đạt được đẳng cấu. Cảm ơn câu trả lời, @mscdex, nó thực sự đã giúp! (trung thực!) – Swivel

11

Nhóm của tôi đã gặp phải sự cố này khi sử dụng Nút với React Native và PouchDB. Dưới đây là cách chúng ta giải quyết nó ...

NPM cài đặt đệm:

$ npm install --save buffer 

Đảm bảo Buffer, btoaatob được nạp như một globals:

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

tôi thấy rằng mặc dù các miếng chêm từ các câu trả lời ở trên đã hoạt động, chúng không khớp với hành vi của việc triển khai các trình duyệt trên máy tính để bàn của 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]))); 

Khi nó quay ra, Buffer trường hợp đại diện/giải thích các chuỗi được mã hóa theo UTF-8 by default. Ngược lại, ở máy tính để bàn của Chrome, bạn có thể thậm chí không đầu vào một chuỗi chứa ký tự bên ngoài của latin1 dao vào btoa(), vì nó sẽ ném một ngoại lệ: Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

Vì vậy, bạn cần phải thiết lập một cách rõ ràng encoding type-latin1 trong để cho shim Node.js của bạn để phù hợp với kiểu mã hóa của Chrome desktop:

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]))); 
3

các giải pháp được đăng ở đây không làm việc trong các ký tự không ascii nếu bạn có kế hoạch để trao đổi base64 giữa Node.js và một trình duyệt. Để làm cho nó hoạt động, bạn phải đánh dấu văn bản đầu vào là 'nhị phân'.

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

này mang đến cho bạn SOlsbPMgd/NybGQhIQ==. Nếu bạn tạo atob('SOlsbPMgd/NybGQhIQ==') trong một trình duyệt, nó sẽ giải mã nó theo đúng cách.Nó sẽ làm điều đó ngay trong Node.js qua:

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

Nếu bạn không làm "phần nhị phân", bạn sẽ giải mã sai ký tự đặc biệt.

Tôi đã nhận nó from the implementation of the btoa npm package:

Các vấn đề liên quan