capacitor
capacitor copied to clipboard
fix(android): Avoid handling redirection response in WebViewLocalServer (#4240)
Fixes #4240
In WebViewLocalServer.handleProxyRequest()
, avoid intercepting network request which will result in a redirection response. This is because intercepting redirection response in handleProxyRequest()
will caused the redirection resolving in HttpURLConnection, rather than in web view. This in turn causes the window URL to be unchanged when we expected it to change after a redirect response.
This indeed fixes my redirect problems! I do however notice that after a redirect, the capacitor and plugin packages have lost all knowledge of the native-bridge (no more device info). It restarts properly after a webview refresh. I'm not sure if this is a side effect of this fix though.
Glad that this works for you both @Moarcoo and @tony-scio
If I recall correctly, one of the side effect to the redirected page is that it will not have the capacitor runtime (ie. the native bridge) as it skipped the jsInjector.getInjectedStream
part which is located right after the if statement.
If I recall correctly, one of the side effect to the redirected page is that it will not have the capacitor runtime (ie. the native bridge) as it skipped the
jsInjector.getInjectedStream
part which is located right after the if statement.
We didn't try changing the order of that. Worth a go.
This is an issue that's been affecting us on Android, too, and while I think this may fix this issue with regards to redirects, there still exists a broader and more substantive difference between how the Capacitor code is injected on iOS and how it's injected on Android. The iOS approach is pretty clean and ensures that the code is always loaded, redirects are handled within the webview, etc. The Android approach, on the other hand, relies on proxying the content and delicately searching for
tags to inject the Capacitor code. We've been experimenting with a fork that we've created that appears to eliminate the need for the handleProxyRequest function altogether.Specifically, we (a) eliminate handleProxyRequest, (b) set the jsInjector property to public on WebViewLocalServer, (c) remove references to jsInjector.getInjectedStream in handleLocalRequest, and (d) in Bridge.java, add to the reset() function a call to webView.evaluateJavascript that executes the script aggregate, which appears to have a pretty equivalent effect as the current behavior. With this new approach, however, no proxying is required, everything can happen in the webview, and we achieve a pretty equivalent behavior between the iOS and Android implementations.
We're happy to submit this as a PR, if folks may think this would be helpful, but I thought I'd chime in here first to see if we're missing some special context as to why this approach hasn't been taken already. The proxy code just seems like it's always going to be a fragile way to handle this remotely-loaded content on Android.
This is an issue that's been affecting us on Android, too, and while I think this may fix this issue with regards to redirects, there still exists a broader and more substantive difference between how the Capacitor code is injected on iOS and how it's injected on Android. The iOS approach is pretty clean and ensures that the code is always loaded, redirects are handled within the webview, etc. The Android approach, on the other hand, relies on proxying the content and delicately searching for tags to inject the Capacitor code. We've been experimenting with a fork that we've created that appears to eliminate the need for the handleProxyRequest function altogether.
Specifically, we (a) eliminate handleProxyRequest, (b) set the jsInjector property to public on WebViewLocalServer, (c) remove references to jsInjector.getInjectedStream in handleLocalRequest, and (d) in Bridge.java, add to the reset() function a call to webView.evaluateJavascript that executes the script aggregate, which appears to have a pretty equivalent effect as the current behavior. With this new approach, however, no proxying is required, everything can happen in the webview, and we achieve a pretty equivalent behavior between the iOS and Android implementations.
We're happy to submit this as a PR, if folks may think this would be helpful, but I thought I'd chime in here first to see if we're missing some special context as to why this approach hasn't been taken already. The proxy code just seems like it's always going to be a fragile way to handle this remotely-loaded content on Android.
@agclark27 We have similar issues with some webapp using Auth0 for login and do redirects for tracking tools. The fix provided in this PR is good enough for our use case, but I'll be very interested to see what solution you came with because as you say this fix doesn't really "fix" the underlying issue with the way webview handle requests.
We've run into this issue using AWS Cognito and this patch fixes the problem as well.
Is there any information when this might be integrated? And is there a fix that also prevents the problem with the missing native bridge?
Hi Capacitor team, this can be fix by any chance? We want to use keycloak and this is the only blocking issue at the moment. Thank you for your work.