React Native atob() / btoa() not working without remote JS debugging

前端 未结 3 741
灰色年华
灰色年华 2020-12-04 15:18

I have a testing app in react native, and all works fine when I have enabled the debug js remotely. It works fine in device (from XCode) and simulator, after run:

         


        
相关标签:
3条回答
  • 2020-12-04 15:48

    That's the ways I fixed it. As @chemitaxis suggests, add base-64 module from NPM:

    npm i -S base-64
    

    Based on it, I propose a couple of ways to use it:

    Importing it in files you need it

    Then, you can import 'encode' and 'decode' methods using aliases, this way:

    import {decode as atob, encode as btoa} from 'base-64'
    

    Of course, using aliases is optional.

    Polyfill way

    You can set atob and btoa as global variables on React Native. Then, you won't need to import them on each file you need it. You have to add this code:

    import {decode, encode} from 'base-64'
    
    if (!global.btoa) {
        global.btoa = encode;
    }
    
    if (!global.atob) {
        global.atob = decode;
    }
    

    You need to place it at the beginning of your index.js, so that it can be loaded before another file uses atob and btoa.

    I suggest you to copy it on a separate file (let's say base64Polyfill.js), and then import it on index.js

    0 讨论(0)
  • 2020-12-04 15:51

    Here you go (https://sketch.expo.io/BktW0xdje). Create a separate component (e.g. Base64.js), import it and it's ready to use. For instance Base64.btoa('123');

    // @flow
    // Inspired by: https://github.com/davidchambers/Base64.js/blob/master/base64.js
    
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    const Base64 = {
      btoa: (input:string = '')  => {
        let str = input;
        let output = '';
    
        for (let block = 0, charCode, i = 0, map = chars;
        str.charAt(i | 0) || (map = '=', i % 1);
        output += map.charAt(63 & block >> 8 - i % 1 * 8)) {
    
          charCode = str.charCodeAt(i += 3/4);
    
          if (charCode > 0xFF) {
            throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
          }
    
          block = block << 8 | charCode;
        }
    
        return output;
      },
    
      atob: (input:string = '') => {
        let str = input.replace(/=+$/, '');
        let output = '';
    
        if (str.length % 4 == 1) {
          throw new Error("'atob' failed: The string to be decoded is not correctly encoded.");
        }
        for (let bc = 0, bs = 0, buffer, i = 0;
          buffer = str.charAt(i++);
    
          ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
            bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
        ) {
          buffer = chars.indexOf(buffer);
        }
    
        return output;
      }
    };
    
    export default Base64;
    
    0 讨论(0)
  • 2020-12-04 16:08

    The main part of your question has been answered, but I see there's still some uncertainty about why it works with remote debugging enabled.

    When debugging remotely, the JavaScript code is actually running in Chrome, and the diffs to the virtual dom are being communicated to the native app over a web socket.

    http://facebook.github.io/react-native/docs/javascript-environment

    atob and btoa are available in the context of the browser, and that's why it works there.

    When you stop debugging, though, the JavaScript is again interpreted in a process on your device or simulator, which doesn't have access to functions that are provided by the browser.

    0 讨论(0)
提交回复
热议问题