在 React Native WebView 中从注入的 JavaScript 接收消息
Posted
技术标签:
【中文标题】在 React Native WebView 中从注入的 JavaScript 接收消息【英文标题】:Receiving message from injected JavaScript in a React Native WebView 【发布时间】:2018-10-19 14:08:27 【问题描述】:在我的 React Native 应用程序中,我使用“injectedjavascript”道具使用 WebView 来显示谷歌广告 (AdSense)。问题是我无法提前知道广告的高度。所以我一开始给它一个随机高度,当它的样式更新时,我打算正确设置它的高度。
我假设我必须在注入的 JS 代码中获取高度,然后使用“window.postMessage()”方法通过“onMessage”属性将其发送到 WebView。
MutationObserver 结合 promise 似乎非常适合这种情况。现在,我只想接收来自 webview 的消息。所以这是我现在的代码,但没有发送任何消息:
export default class App extends Component
constructor(props)
super(props);
_onMessage(e)
console.warn(e.nativeEvent.data);
render()
const jsCode = `
window._googCsa('ads', pageOptions, adblock1);
function waitForAdSense(id)
var config =
attributes: true,
attributeFilter: ['style'],
;
return new Promise((resolve, reject) =>
var adSenseElement = document.body.getElementById(id);
if (adSenseElement.style)
resolve(adSenseElement.style.height);
return;
var observer = new MutationObserver(function(mutations)
mutations.forEach(function(mutation)
if (mutation.attributeName === 'style')
observer.disconnect();
resolve(adSenseElement);
return;
);
);
observer.observe(adSenseElement, config);
);
waitForAdSense('afscontainer1').then(height =>
window.postMessage(height, '*');
);
`;
return (
<ScrollView>
<WebView
key='AdSense'
ref='webview2'
style= height: 300
source=
uri: isandroid
? 'file:///android_asset/widget/adSense.html'
: './widget/index.html',
javaScriptEnabled=true
mixedContentMode="compatibility"
injectedJavaScript=jsCode
scrollEnabled=false
domStorageEnabled=true
onMessage=this._onMessage
scalesPageToFit
startInLoadingState=true
automaticallyAdjustContentInsets=false
/>
;
</ScrollView>
);
虽然,我可以让它与这段代码一起工作,但 setTimeout 不是最好的解决方案:
window._googCsa('ads', pageOptions, adblock1);
var adSenseContainer = document.getElementById("afscontainer1");
setTimeout(function() window.postMessage(adSenseContainer.style.height, '*'); ,1000);
你有什么想法吗?我认为我的函数 waitForAdSense() 可能会以某种方式被窃听。提前致谢!
【问题讨论】:
为什么使用 AdSense 而不是 AdMob? 此特定广告是 iframe,需要在 WebView 中实现。 那么这个特定的广告可能需要使用移动标准实施到移动设备上 【参考方案1】:最好的解决方案是在 React Native 移动应用程序上使用 AdMob 而不是 AdSense。由于 AdSense javascript 没有考虑到这个用例,因此处理这些问题是毫无意义的。这是一个 library,可轻松将 AdMob 集成到您的应用中。
【讨论】:
【参考方案2】:我设法使它与注入代码中的这些更改一起工作:
window._googCsa('ads', pageOptions, adblock1);
function waitForAdSense()
var config =
attributes: true,
attributeFilter: ["style"]
;
var adSenseContainer = document.getElementById("afscontainer1");
return new Promise((resolve, reject) =>
var observer = new MutationObserver(function (mutations)
mutations.forEach(function (mutation)
if (mutation.attributeName === 'style' && adSenseContainer.style.height)
var height = adSenseContainer.style.height;
resolve(height);
observer.disconnect();
return;
;
);
);
observer.observe(adSenseContainer, config);
);
;
waitForAdSense().then(height =>
window.postMessage(height, '*');
);
感谢您的建议!
【讨论】:
以上是关于在 React Native WebView 中从注入的 JavaScript 接收消息的主要内容,如果未能解决你的问题,请参考以下文章
从 React Native App 中的 WebView 打开动态链接
WebView(react-native-webview)在 Expo SDK36 中获取错误代码 -1
React-native:如何自动保存 webview 当前网页?