react-native - 使用 React Native 的 WebView 获取 JSON 的正确方法
问题描述
似乎 WebView 在 react-native 中扮演着类似的网络工作者角色。
我正在尝试将繁重的数据提取卸载到 WebView,但它似乎非常痛苦,并且找不到fetch
带有WebView
.
所以我有下面的 JavaScript 代码,我试图用它来调用 API。
当使用来自常规 react-native 类的完全相同的代码时,可以完美地获取和解析 JSON 响应。
但是,当将相同的 JavaScript 代码注入到带有injectJavaScript
方法的 WebView 中时,该Content-Type
值会导致问题。(当我删除它时,我从后端看到调用已完成,但我无法在前端 - WebView 端获取 JSON 数据。)
即使 API 后端允许所有跨域请求,它似乎也与 cors 有关。
结果,我的问题是:
- 在 react-native 中使用 fetch 和 WebView 的正确方法是什么?
- 为什么 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 的原因。(看来将来这将适用于世博会)。
解决方案
更新
以下代码片段,我通过 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
}
推荐阅读
- python - 在pyqtgraph中绘制一个矩形
- windows - 无法使用 netcat 从端口 1300 上的主机连接到访客 docker 容器
- powershell - PowerShell 根据文件大小搜索文件
- node.js - NodeJS Express 中使用 JWT 的双重身份验证器
- c++ - OpenCV:输出图像为蓝色
- python - 没有重复字符的最长子串” Leetcode 递归解决方案不起作用
- swift - 无法推断通用参数“S”+对成员“计数”的不明确引用
- excel - 使用输入框将另一个工作簿引用到子
- javascript - 如何解决 Nodemailer 设置的问题
- java - JDK11 的 checkSystemClipboardAccess 替代方案