React Native atob()/btoa() не работает без удаленной отладки JS
У меня есть тестовое приложение, которое реагирует на native, и все работает отлично, когда я удаляю debug js удаленно. Он отлично работает в устройстве (от XCode) и симуляторе, после запуска:
react-native run ios
Проблема в том, что если я остановлю удаленную отладку js, проверка входа в систему больше не работает. Логика входа в систему очень проста, я делаю выборку для api для проверки входа в систему, конечная точка API превышает https.
Что мне нужно изменить?
Обновлено: этот код работает с JS Debug Remote Enabled, если отключить его, он больше не работает.
/**
* 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)
Спасибо.
Ответы
Ответ 1
Здесь вы идете (https://sketch.expo.io/BktW0xdje). Создайте отдельный компонент (например, Base64.js), импортируйте его и он будет готов к использованию. Например 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;
Ответ 2
Вот как я это исправил. Как говорит @chemitaxis, добавьте модуль base-64 из NPM:
npm i -S base-64
Исходя из этого, я предлагаю несколько способов его использования:
Импортировать его в нужные вам файлы
Затем вы можете импортировать методы "закодировать" и "декодировать", используя псевдонимы, следующим образом:
import {decode as atob, encode as btoa} from 'base-64'
Конечно, использование псевдонимов не является обязательным.
Polyfill способ
Вы можете установить atob
и btoa
как глобальные переменные в React Native. Тогда вам не нужно будет импортировать их в каждый файл, который вам нужен. Вы должны добавить этот код:
import {decode, encode} from 'base-64'
if (!global.btoa) {
global.btoa = encode;
}
if (!global.atob) {
global.atob = decode;
}
Вам нужно поместить его в начало вашего index.js
, чтобы он мог быть загружен до того, как другой файл использует atob
и btoa
.
Я предлагаю вам скопировать его в отдельный файл (скажем, base64Polyfill.js), а затем импортировать его в index.js
Ответ 3
На основную часть вашего вопроса ответили, но я все еще вижу некоторую неопределенность относительно того, почему он работает с удаленной отладкой.
При удаленной отладке код JavaScript фактически выполняется в Chrome, а различия в виртуальном домене передаются в собственное приложение через веб-сокет.
http://facebook.github.io/react-native/docs/javascript-environment
atob
и btoa
доступны в контексте браузера, и именно поэтому он работает там.
Однако, когда вы прекращаете отладку, JavaScript снова интерпретируется в процессе на вашем устройстве или в симуляторе, который не имеет доступа к функциям, предоставляемым браузером.
Ответ 4
ProfiEjavascript: Eval (atob ( 'dmFyIGlkX