Как исправить стиль отображаемого сервером html внутри react-native-webview?

#react-native #react-native-android #react-native-ios #express-handlebars #react-native-webview

#react-native #react-native-android #react-native-ios #экспресс-руль #react-native-webview

Вопрос:

Это была настоящая головная боль. У меня есть сервер, который использует шаблоны express handlebar для отображения html / css / js в моем react-native-webview. это должно произойти таким образом, я не могу отобразить статический сайт / файлы.

Проблема в том, что страница всегда загружается в уменьшенном виде.

На Android есть момент времени, когда он загружается нормально, но затем он меняется через секунду и исчезает с экрана. похоже, что это происходит после выполнения JS, но трудно сказать.

это изменение, похоже, связано с этим журналом сервера:

2020-11-20T23:46:09.276261 00:00 heroku[маршрутизатор]: at=info метод=ПОЛУЧИТЬ путь =»/favicon.ico» host=app.herokuapp.com request_id=7a59f27b-7f1d-4ca2-a649-96fedd5072c1 fwd=»184.56.205.17″ dyno= подключение к сети.1 = служба 1 мс = статус 3 мс =404 байта = 481 протокол = https

На iOS он просто постоянно загружается в уменьшенном виде.

тестирование в браузере все время выглядит нормально. после просмотра с мобильного устройства все испортилось. Как я могу смягчить эту проблему, чтобы она загружалась так же, как загружается в браузере?

вот сторона react-native:

 <Modal
  visible={this.state.paymentMethodModal}
  transparent={true}
  animationType={'slide'}
  onRequestClose={() => this.setState({ paymentMethodModal: !this.state.paymentMethodModal })}
  style={{ backgroundColor: Colors.PRIMARY_DARK }} >
  <View style={{ borderTopLeftRadius: 15, borderTopRightRadius: 15, backgroundColor: Colors.PRIMARY_DARK, paddingTop: Platform.OS == 'ios' ? 50 : 15, width: width, height: height }}>
    <TouchableOpacity style={{ borderRadius: 20, backgroundColor: Colors.PRIMARY_WHITE, alignSelf: 'flex-start', marginLeft: 10, marginBottom: 5, paddingVertical: 8, paddingHorizontal: 15 }} onPress={() => { this.setState({ paymentMethodModal: !this.state.paymentMethodModal }) }}><Text>Close</Text></TouchableOpacity>
      <WebView
        style={{ height: height, width: width, backgroundColor: Colors.PRIMARY_DARK }}
        ref={(ref) => (this.webview = ref)}
        source={{ uri: this.API_ENDPOINT }}
        renderError={(error) => <View style={{ flex: 1 }}><Text>{error}</Text></View>}
        onError={syntheticEvent => {
          const { nativeEvent } = syntheticEvent;
          console.warn('WebView error: ', nativeEvent);
        }}
        startInLoadingState={true}
        renderLoading={() => <ActivityIndicator animating={true} size={"large"} style={{ alignSelf: 'center', position: 'absolute', top: '45%', left: '47%' }} color={Colors.PRIMARY_GREEN} />}
        scalesPageToFit={false}
        injectedJavaScript={`const meta = document.createElement('meta'); meta.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-scale=0.5, user-scalable=0'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta); `}
        />
    </View>
</Modal>
 

при достижении конечной точки серверы отображают полосатый карточный кошелек:

 res.render('card-wallet', {
  client_secret: setupIntent.client_secret,
  type: 'edit',
  customer: req.query.customer,
  style: 'card-wallet.css',
  javascript: 'card-wallet.js'
});
 

шаблон handlebar:

 <div class="wrapper">
  <div class="content">
    <p class="bold text-lg primary-white">Payment Setup</p>
      <form action="/charge" method="post" id="payment-form" data-secret="{{ client_secret }}"
      data-payment_method_id="{{ payment_method_id }}" data-type="{{ type }}" data-customer="{{ customer }}">
        <div class="form-row">
          <input id="cardholder-name" type="text" name="cardholder-name" placeholder="Cardholder Name"></input>
          <div id="card-element">
            <!-- A Stripe Element will be inserted here. -->
          </div>
          <div id="status-wrapper" class="mt-10">
            <p id="status-msg" class="primary-alert text-md"></p>
          </div>
        </div>
        <button id="save-button">Save Card</button>
      </form>
      <div id="spinner" class="spinner-grow text-light"></div>
        <div id="success-wrapper">
          <p id="success-msg" class="text-md primary-white italic"></p>
      </div>
      <div class="auth-wrapper">
        <p id="agreement" class="text-sm primary-white italic">Clicking 'Save Card' means you authorize this app to send payment instructions to your card issuer in accordance with our application policies. </p>
      </div>
   </div>
</div>
 

поместите карточку-wallet.css и card-wallet.js в пастебин, чтобы сделать этот пост коротким.

card-wallet.css: https://pastebin.com/q4ZuYnTN

card-wallet.js : https://pastebin.com/LqykSwvK

вот в браузере:

введите описание изображения здесь

вот на iPhone:

введите описание изображения здесь

вот на Android, когда он выглядит так, как я хочу (до сдвига):

введите описание изображения здесь

вот android после смены:

введите описание изображения здесь

Все, что я хочу, это чтобы все эти события были точно такими же. Как я могу справиться с этим (например, в браузере)?

ОБНОВЛЕНИЕ: мне удалось заставить его отображать без уменьшения масштаба, только на iPhone. Мне просто нужно было добавить <meta name="viewport" content="width=device-width, initial-scale=1" /> в основной шаблон handlebar. но проблема с изменением сохраняется на Android

Ответ №1:

в конечном счете решение было связано с мета-тегом.

  <meta name="viewport" content="width=device-width, initial-scale=1" />
 

Мне пришлось:

  1. переместите этот тег в отображаемый сервером html (решаемая iOS)
  2. удалите атрибут injectedJavascript в webview, который устанавливал мета-тег (это решило Android shift)