首页 > 解决方案 > 使用 React Native 的 WebView 获取 JSON 的正确方法

问题描述

似乎 WebView 在 react-native 中扮演着类似的网络工作者角色。

我正在尝试将繁重的数据提取卸载到 WebView,但它似乎非常痛苦,并且找不到fetch带有WebView.

所以我有下面的 JavaScript 代码,我试图用它来调用 API。

当使用来自常规 react-native 类的完全相同的代码时,可以完美地获取和解析 JSON 响应。

但是,当将相同的 JavaScript 代码注入到带有injectJavaScript方法的 WebView 中时,该Content-Type值会导致问题。(当我删除它时,我从后端看到调用已完成,但我无法在前端 - WebView 端获取 JSON 数据。)

即使 API 后端允许所有跨域请求,它似乎也与 cors 有关。

结果,我的问题是:

  1. 在 react-native 中使用 fetch 和 WebView 的正确方法是什么?
  2. 为什么 react-native 和 WebView 的行为不同?
var l_headers = {
   Accept: 'application/json',
   'Content-Type': 'application/json'
};
var l_init = {
    method: "POST",
    headers: l_headers,
    body: {}
};
fetch("http://172.20.10.12:8000/test", l_init).then(function (response) {
    return response.json();
}).then(function (responseJson) {
    alert('API called: ' + JSON.stringify(responseJson));
});

PS:最后一个让分,请注意我也在使用EXPO,因为它的好处而无法弹出。这就是为什么我今天不能使用 react-native-community 的 react-native-webview 的原因。(看来将来这将适用于世博会)。

标签: react-nativewebviewfetch

解决方案


更新
以下代码片段,我通过 POST fetch 获取 JSON,一旦获取响应,就会显示在警报中。这是一个有效的小吃博览会链接

  injectjs() {
    let jsCode = `const bodyData = JSON.stringify({
      title: 'foo',
      body: 'bar',
      userId: 1
    });
    fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: bodyData,
    }).then(response => response.text()).then(valueText => {
      alert(JSON.stringify(valueText));
    });`;
    return jsCode;
  }

  render() {
    return (
      <View style={styles.container}>
       <WebView
          ref={webview => { this.webview = webview; }}
          source={{
            uri: "https://www.google.com"
            }}
            injectedJavaScript={this.injectjs()}
            javaScriptEnabled = {true}
            style={styles.webview}
          />
      </View>
    );
  }

旧答案 当我需要在 HTML 之间进行通信和反应原生代码时,
我通常在 ReactNative WebView 中使用。postMessage

  • 发送消息以响应本机的 HTML 代码
    postMessage(JSON.stringify(yourJson), '*');
  • 从反应原生接收消息

    document.addEventListener('message',(event) => {
    eval(event, data)
    }, false)

  • 反应本机 WebView
    <WebView
           ref={webview => { this.webview = webview; }}
           source={anySource}
           injectedJavaScript={script}
           javaScriptEnabled = {true}
           onMessage={this.onMessage}
           onNavigationStateChange = {this.handleNavigation}
         />
  • 接收消息

    onMessage = (e) => {
     let { data } = e.nativeEvent; // data you will receive from html
    }

  • 发布消息
    this.webview.postMessage('YourMessage')

如果postMessage在 expo 中不起作用,您可以改用onShouldStartLoadWithRequest/onNavigationStateChange 方法。

    handleNavigation = (event) => {
        const url = event.url;
        const sections = url.split('#');
        if(sections.length > 1 && sections[1].indexOf('message=') != -1) {
           const message = sections[1[.replace('message=', '');
           //Do any action with message
           return;
        }
        //Other navigation actions
      }

推荐阅读