使用React Native的WebView提取JSON的正确方法

时间:2019-02-23 20:42:54

标签: react-native webview fetch

WebView似乎在响应本地人员方面扮演着类似Web工作者的角色。

我正在尝试将大量数据提取工作转移到WebView,但似乎很痛苦,找不到带有fetch的{​​{1}}示例。

所以下面有我要用来调用API的JavaScript代码。

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

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

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

结果,我的问题是:

  1. 在react-native中将提取与WebView一起使用的正确方法是什么?
  2. 为什么react-native和WebView的行为不同?
Content-Type

PS:最后一个障碍,请注意,我也在使用EXPO,但由于其优势而无法退出。这就是为什么到目前为止我不能使用react-native-community的react-native-webview的原因。 (看来将来它将适用于EXPO。)

1 个答案:

答案 0 :(得分:4)

更新
遵循以下代码片段,我通过POST提取来获取JSON,并且一旦获取,响应就会显示在alert中。这是工作中的Snack Expo Link

  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在博览会上不起作用,您可以改用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
      }