Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
654 views
in Technique[技术] by (71.8m points)

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

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:

react-native run ios

The problem is that if I stop remote js debugging, the login test not works anymore.The login logic is very simple, I'm making a fetch to an api to test a login, the API endpoint is over https.

What I need to change?

Updated: This code works perfetly with JS Debug Remote Enabled, if I disable it, it not works anymore.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,      
  View,
  Button,
  Alert
} from 'react-native'

export default class MyClass extends Component {

  constructor (props) {
    super(props)
    this.testFetch = this.testFetch.bind(this)
  }

  async testFetch () {
    const email = '[email protected]'
    const password = '123456'

    try {
      const response = await fetch('https://www.example.com/api/auth/login', {
        /* eslint no-undef: 0 */
        method: 'POST',
        headers: {
          'Accept': 'application/json' /* eslint quote-props: 0 */,
          'Content-Type': 'application/json',
          'Authorization': 'Basic ' + btoa(email + ':' + password)
        }

      })
      Alert.alert('Error fail!', 'Fail')
      console.log(response)
    } catch (error) {
      Alert.alert('Error response!', 'Ok')
    }
  }

  render () {
    return (
      <View style={styles.container}>            
        <Button
          onPress={this.testFetch}
          title="Test me!"

        />            
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF'
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5
  }
})

AppRegistry.registerComponent('testingReactNative', () => MyClass)

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...