react-native-webview: onShouldStartLoadWithRequest not working consistently across different platforms

"react": "16.6.3", "react-native": "0.58.5", "react-native-webview": "^5.2.1"

on iOS : onShouldStartLoadWithRequest event fires 3 TIMEs with 3 different URLs on Android: onShouldStartLoadWithRequest event fires 1 TIME with 1 URL

async requests/iframe ignored on android ?

UPDATE: i did a little research , found this https://stackoverflow.com/questions/26651586/difference-between-shouldoverrideurlloading-and-shouldinterceptrequest/26652169 may be we should use shouldInterceptRequest method instead of shouldOverrideUrlLoading on Android , since it captures all request(css/script/iframe/ajax…), make it more consistent with iOS behavior ?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 21 (3 by maintainers)

Most upvoted comments

@ericlathrop , were you able to solve it? Could you assist me?

I have this implementation:

<WebViewAutoHeight
                key={s.Body.substr(10)}
                source={{
                  //prettier-ignore
                  html: `<body style="font-family: -apple-system, Roboto, sans-serif; background-color: ${lightTheme.grey2} !important; color: ${v2Colors.charcoalDarkest}; font-size: ${moderateScale(14, 0.2)}px;">${s.Body}</body>`
                }}
                // onShouldStartLoadWithRequest={request => {
                //   if (Platform.OS === "android") {
                //     const url = request.url;
                //     console.log(request);
                //     if (url !== uri) {
                //       Linking.openURL(url);
                //     }
                //     // return false;
                //   }
                // }}
                onNavigationStateChange={event => {
                  if (Platform.OS === "ios") {
                    if (event.url !== uri) {
                      Linking.openURL(event.url);
                    }
                  }
                }}
              />

So onShouldStartLoadWithRequest works for Android and onNavigationStateChange works for iOS, but even if I add an if conditional checking for Platform.OS they are still somehow interacting in a way that its causing problem on iOS where the webview does not completely load up. I tried placing wrapping the properties and their respective logic inside a big if/else and even an ternary but I kept getting syntax errors.

@gfpacheco I ended up writing a blacklist of URL prefixes to ignore. Far from ideal. At least I stored the blacklist in Firebase so I can update it without having to push a new version of my app.

@c1ngular

Can I ask, how did you expose shouldInterceptRequest to the React Native side? Did you fork the webview, or is there another way. Thanks in advance!

@ldco2016 @2xSamurai Here’s my workaround for this issue:

const webViewAllowedEmbeddingUrlPrefixes = [
  "https://m.facebook.com/plugins/video.php",
  "https://platform.twitter.com/jot.html",
  "https://syndication.twitter.com/i/jot",
  "https://www.facebook.com/plugins/video.php",
  "https://www.scribd.com/embeds/",
  "https://www.youtube.com/embed/",
];
const webViewAllowedEmbeddingUrlRegexes = [
  "https://www.iheart.com/podcast/.*\\?embed=true"
];
const webViewRestrictedEmbeddingUrlPrefixes = [
  "https://accounts.google.com/o/oauth2/iframe",
  "https://clearchannel.demdex.net/",
  "https://staticxx.facebook.com/connect/",
  "https://synchroscript.deliveryengine.adswizz.com/",
  "https://www.facebook.com/connect/",
];
function onShouldStartLoadWithRequest(request) {
  if (request.url === "about:blank") {
    return true;
  }

  // HACK: allow some urls to be embedded, and reject others
  // https://github.com/react-native-community/react-native-webview/issues/381
  if (Platform.OS === 'ios') {
    if (webViewAllowedEmbeddingUrlPrefixes.some(prefix => request.url.indexOf(prefix) === 0)) {
      return true;
    }
    if (webViewAllowedEmbeddingUrlRegexes.map(r => new RegExp(r)).some(regexp => request.url.match(regexp) !== null)) {
      return true;
    }
    if (webViewRestrictedEmbeddingUrlPrefixes.some(prefix => request.url.indexOf(prefix) === 0)) {
      return false;
    }
  }

  Linking.openURL(request.url)
    .catch(err => console.error(`Could not open URL ${request.url}`, err));
  return false;
}

@ericlathrop I want the same thing, did you manage to make it work? I only want to intercept what would be changes to the window.href, not all the background requests

Hey folks, I am also stuck in this is an issue from webview and finally am fix this issue by getting a fork from react-native-community/react-native-webview by doing some android native code. You guys check out my git package.

https://github.com/kulbhushan-ucreate/react-native-web-view.

I’m having a problem with onShouldStartLoadWithRequest acting differently on iOS vs Android.

I’m using source={{html: myHtml}} to inject my HTML and then onShouldStartLoadWithRequest to open any links the user clicks on in an external browser like this:

function onShouldStartLoadWithRequest(request) {
  Linking.openURL(request.url)
    .catch(err => console.error(`Could not open URL ${request.url}`, err));
  return false;
}

My problem is that on iOS this function gets called for embedded Youtube videos, which I believe are iframes. On Android, this function is only called when the user taps on something.

I’d prefer onShouldStartLoadWithRequest to act like Android’s version on iOS. If that’s not possible I’d like some way to distinguish URLs opened from embedded content from URLs opened from user clicks.

Have the same issue with the Youtube iframe player being catched with onShouldStartLoadWithRequest() on iOS Are there alternative ways to resolve this?

@Titozzz willingly , i tried couple of times, but i could not make it work , i walked thought this repo and followed the implementation of shouldOverrideUrlLoading ,no avail. for most of the steps , i was justing shooting in the dark , i have zero experience of mobile development . sorry~

Feel free to submit a PR cc @maxammann