Bug description:
I noticed originWhitelist does not behave the same in iOS and Android.
In Android originWhitelist works as expected, preventing navigation to other domains within the webview.
But in iOS it also filters out all non-navigation related requests (medias, embedded content, tracking).
There is a workaround I found in issues and comments from the repo (see #541, #1505), using onShouldStartLoadWithRequest & navigationType === "click" to handle wether or not to load a request.
But this does not work for Android, as the navigationType(NativeSyntheticEvent), exposed in onShouldStartLoadWithRequest only exists in iOS. So that we cannot filter navigations on user clicks from all other requests (medias, embedded content, tracking).
To Reproduce:
const DOMAIN_WHITELIST = ['github.com'];
const ORIGIN_WHITELIST = ['https://github.com/'];
const WebviewWrapper = () => {
const webViewRef = useRef<WebView>(null);
/* ... */
const handleLoadRequest = (event: ShouldStartLoadRequest) => {
const { url, navigationType } = event;
const urlHostName = new URL(url).hostname;
if (!DOMAIN_WHITELIST.includes(urlHostName) && navigationType === 'click') {
Linking.canOpenURL(url)
.then((supported) => {
if (supported) {
Linking.openURL(url);
} else {
Alert.alert('Error', `Could not open the following URL: ${url}`);
}
})
.catch(() => {
Alert.alert('Error', `Could not open the following URL: ${url}`);
});
return false; // Prevent WebView from loading the URL
}
return true;
};
return (
<WebView
ref={webViewRef}
style={styles.webview}
startInLoadingState
domStorageEnabled
allowsBackForwardNavigationGestures
onNavigationStateChange={onNavigationStateChange}
onShouldStartLoadWithRequest={handleLoadRequest} // in Android this is blocking all requests as Android does not expose "navigationType"
mixedContentMode='compatibility'
originWhitelist={ORIGIN_WHITELIST} // in iOS this will not let cdn images and embedded content to be requested
onContentProcessDidTerminate={() => webViewRef.current?.reload()}
/>
);
};
This is my current workaround for it:
<WebView
//...
onShouldStartLoadWithRequest={
Platform.OS === 'ios' ? handleLoadRequest : undefined
}
originWhitelist={Platform.OS === 'android' ? ORIGIN_WHITELIST : undefined}
//...
/>
I do not get how and why it is not behaving the same way, the source code where originWhitelist and onShouldStartLoadWithRequest are being used looks pretty simple :
|
const createOnShouldStartLoadWithRequest = ( |
Seems like the method is not called on the same events depending on the platform. 🤔
Expected behavior:
I would expect originWhitelist to behave the same for each platform: only blocking navigation and not blocking requests for cdn images, embedded content etc... So we wouldn't need to handle iOS requests in onShouldStartLoadWithRequest, for basic usages.
Or maybe have separated whitelists to distinguish navigation from all other requests ? 🤔
If this is an expected/known behavior, that depends on platform specific constraints, it would be great to add some documentation for it.
Environment:
- OS: iOS & Android
- OS version: iOS 17 & SDK 32
- react-native version: 0.73.6
- react-native-webview version: 13.6.4
Bug description:
I noticed
originWhitelistdoes not behave the same in iOS and Android.In Android
originWhitelistworks as expected, preventing navigation to other domains within the webview.But in iOS it also filters out all non-navigation related requests (medias, embedded content, tracking).
There is a workaround I found in issues and comments from the repo (see #541, #1505), using
onShouldStartLoadWithRequest&navigationType === "click"to handle wether or not to load a request.But this does not work for Android, as the
navigationType(NativeSyntheticEvent), exposed inonShouldStartLoadWithRequestonly exists in iOS. So that we cannot filter navigations on user clicks from all other requests (medias, embedded content, tracking).To Reproduce:
This is my current workaround for it:
I do not get how and why it is not behaving the same way, the source code where
originWhitelistandonShouldStartLoadWithRequestare being used looks pretty simple :react-native-webview/src/WebViewShared.tsx
Line 40 in 2b86b63
Seems like the method is not called on the same events depending on the platform. 🤔
Expected behavior:
I would expect
originWhitelistto behave the same for each platform: only blocking navigation and not blocking requests for cdn images, embedded content etc... So we wouldn't need to handle iOS requests inonShouldStartLoadWithRequest, for basic usages.Or maybe have separated whitelists to distinguish navigation from all other requests ? 🤔
If this is an expected/known behavior, that depends on platform specific constraints, it would be great to add some documentation for it.
Environment: