> Как передаются данные и токены между нативным приложением и React WebView (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Spotware

Стек: React

> Пример ответа

Короткий ответ

Данные и токены передаются между нативным приложением и React WebView через postMessage API, URL-схемы, инжекцию JavaScript (evaluateJavascript) и нативные мосты (WebView JavaScript bridge). Для токенов используется инжекция в window объект или передача через заголовки запросов. React Native WebView предоставляет unified API через onMessage и postMessage. Безопасность обеспечивается проверкой origin и шифрованием чувствительных данных.

Подробное объяснение

Взаимодействие между нативным кодом и WebView строится на двух направлениях: нативный → WebView и WebView → нативный.

Нативный → WebView:

  • JavaScript injection - нативный код вызывает evaluateJavascript (Android) или evaluateJavaScript (iOS), передавая строку с JS-кодом. Это основной способ передачи токенов и конфигурации. Код выполняется в контексте страницы WebView.
  • URL intercepting - нативный код перехватывает запросы WebView через shouldOverrideUrlLoading (Android) или decidePolicyForNavigationAction (iOS), извлекая данные из URL-схемы (например, myapp://token?value=xxx).
  • Custom headers - токены могут быть добавлены в заголовки всех HTTP-запросов WebView через нативный код.

WebView → нативный:

  • postMessage API - стандартный механизм: JS вызывает window.ReactNativeWebView.postMessage(data), нативный код получает сообщение через onMessage handler. Данные передаются как строка, обычно JSON.
  • URL scheme navigation - JS меняет window.location на кастомную схему (например, app://action?data=...), нативный код перехватывает и парсит.

React Native WebView упрощает оба направления:

  • injectedJavaScript prop для передачи кода при загрузке
  • injectedJavaScriptBeforeContentLoaded для инжекции до загрузки DOM
  • onMessage callback для получения сообщений
  • postMessage метод ref для отправки из React Native

Безопасность:

  • Токены не должны передаваться через URL (остаются в логах)
  • Использовать originWhitelist для ограничения источников
  • Валидировать origin в onMessage
  • Избегать хранения токенов в localStorage WebView (доступно JS)
  • Предпочитать инжекцию токена в замыкание, а не в глобальную переменную

На практике

Выбор стратегии зависит от сценария:

  • Initial load с токеном - инжекция через injectedJavaScriptBeforeContentLoaded. Токен доступен сразу при монтировании React-приложения в WebView.
  • Динамическая передача - через postMessage и onMessage. React Native отправляет команду, WebView отвечает.
  • Однонаправленная передача токена - через заголовки запросов (нативный код перехватывает все запросы и добавляет Authorization header).
  • Callback от WebView - всегда через postMessage. Нативный код слушает onMessage и диспатчит события.

React Native WebView (пример):

JSX
<WebView
source={{ uri: 'https://app.example.com' }}
injectedJavaScriptBeforeContentLoaded={`
window.__TOKEN__ = '${token}';
true;
`}
onMessage={(event) => {
const data = JSON.parse(event.nativeEvent.data);
// обработка
}}
ref={webViewRef}
/>

Обработка ошибок:

  • Таймаут на ответ от WebView (если WebView не загрузился)
  • Retry механизм при сбое postMessage
  • Логирование всех сообщений для дебага

Пример кода

JAVASCRIPT
// React Native (нативный код)
import React, { useRef, useCallback } from 'react';
import { WebView } from 'react-native-webview';
const AuthWebView = ({ token, onAuthResult }) => {
const webViewRef = useRef(null);
// Инжекция токена при загрузке
const injectedJS = `
window.__AUTH_TOKEN__ = '${token}';
// Скрываем токен от сторонних скриптов
Object.defineProperty(window, '__AUTH_TOKEN__', {
writable: false,
configurable: false
});
true;
`;
// Отправка команды в WebView
const sendToWebView = useCallback((action, payload) => {
webViewRef.current?.postMessage(JSON.stringify({ action, payload }));
}, []);
// Получение сообщений от WebView
const handleMessage = useCallback((event) => {
try {
const { type, data } = JSON.parse(event.nativeEvent.data);
if (type === 'AUTH_RESULT') {
onAuthResult(data);
}
} catch (error) {
console.error('Invalid message from WebView:', error);
}
}, [onAuthResult]);
return (
<WebView
ref={webViewRef}
source={{ uri: 'https://app.example.com/auth' }}
injectedJavaScriptBeforeContentLoaded={injectedJS}
onMessage={handleMessage}
javaScriptEnabled={true}
domStorageEnabled={false} // отключаем localStorage для безопасности
originWhitelist={['https://app.example.com']}
/>
);
};
// React-приложение внутри WebView
// window.__AUTH_TOKEN__ доступен сразу
// Отправка результата в нативный код:
const sendToNative = (data) => {
if (window.ReactNativeWebView?.postMessage) {
window.ReactNativeWebView.postMessage(JSON.stringify({
type: 'AUTH_RESULT',
data
}));
}
};

Как отвечать на собеседовании

  1. Начни с ключевых механизмов: postMessage, evaluateJavascript, URL-схемы.
  2. Раздели направления передачи: native→web и web→native.
  3. Упомяни React Native WebView как абстракцию, которая унифицирует платформенные различия.
  4. Обсуди безопасность: почему токены нельзя передавать через URL, как защитить от XSS.
  5. Приведи конкретный сценарий: например, передача JWT токена для авторизации.
  6. Упомяни trade-off: evaluateJavascript быстрее, но postMessage безопаснее для двусторонней связи.
  7. Будь готов к follow-up: "Как обработать случай, когда WebView не загрузился?" (таймаут, fallback UI).

Что проверяет интервьюер

  • Понимание архитектуры гибридных приложений
  • Знание механизмов IPC (inter-process communication) в мобильных платформах
  • Умение проектировать безопасную передачу чувствительных данных
  • Опыт работы с React Native WebView и его API
  • Понимание ограничений WebView (песочница, CORS, доступ к нативным API)
  • Способность выбрать правильный механизм под конкретную задачу

Типичные ошибки

  • Передача токена через URL query params - токен остается в истории браузера, логах, может быть перехвачен.
  • Хранение токена в localStorage WebView - доступно любому JS на странице, уязвимо для XSS.
  • Использование window.postMessage вместо ReactNativeWebView.postMessage - не сработает, так как WebView изолирован.
  • Игнорирование проверки origin в onMessage - любой iframe может отправить сообщение.
  • Синхронная передача больших данных - postMessage асинхронный, нужно обрабатывать коллбэки.
  • Отсутствие обработки ошибок при парсинге JSON - краш приложения при невалидном сообщении.
  • Инжекция токена без экранирования - если токен содержит спецсимволы, JS сломается (использовать JSON.stringify).

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью