Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WebView] Does not follow redirects. #25351

Closed
dakamojo opened this issue Dec 14, 2018 · 26 comments
Closed

[WebView] Does not follow redirects. #25351

dakamojo opened this issue Dec 14, 2018 · 26 comments
Labels
c: new feature Nothing broken; request for a new capability p: webview The WebView plugin package flutter/packages repository. See also p: labels.

Comments

@dakamojo
Copy link

The webview_flutter plugin does not appear to follow redirects. It simply displays a blank white page. This is an example of a URL that has a redirect for the flutter.io website. (this is a Google Ad link)

https://www.googleadservices.com/pagead/aclk?sa=L&ai=DChcSEwis9JrFup7fAhVbuMAKHTNtA5gYABAAGgJpbQ&ohost=www.google.com&cid=CAESQeD2UsU5H7fGhUZOPtY-kPyuOuLkiFu02AYGI7ZI1pHvfjhZaQhzWkZiIC9SuCSp_y7E9WnDpUNypnNzx0oBS6Nm&sig=AOD64_2AaG88ZD2HKakgg_Zdck7rnkTkZA&q=&ved=2ahUKEwjrpJHFup7fAhXMi60KHSYZD4QQ0Qx6BAgPEAE&adurl=

@zoechi zoechi added c: new feature Nothing broken; request for a new capability plugin p: webview The WebView plugin labels Dec 14, 2018
@zoechi zoechi added this to the Goals milestone Dec 14, 2018
@knitero
Copy link

knitero commented Dec 19, 2018

Experiencing the same issue! Any update on this issue?

@zoechi
Copy link
Contributor

zoechi commented Dec 19, 2018

@knitero upvoting the initial comment would rise the priority.

@rakeshlanjewar
Copy link

rakeshlanjewar commented Feb 12, 2019

This is just a little hack for android for this issue. not to use in production because i don't know the side effect of this code. taken from this answer https://stackoverflow.com/a/33264935/7416454

steps:-

step1:- Clone webview_flutter repo.
step2:- add + prefixed text to packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java

package io.flutter.plugins.webviewflutter;
import android.content.Context;
import android.view.View;
import android.webkit.WebView;
+ import android.webkit.WebViewClient;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.platform.PlatformView;
import java.util.List;
import java.util.Map;

public class FlutterWebView implements PlatformView, MethodCallHandler {
  private static final String JS_CHANNEL_NAMES_FIELD = "javascriptChannelNames";
  private final WebView webView;
  private final MethodChannel methodChannel;

  @SuppressWarnings("unchecked")
  FlutterWebView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
    webView = new WebView(context);

+    webView.setWebViewClient(new WebViewClient() {
+      @Override
+   public boolean shouldOverrideUrlLoading(WebView view, String url) {
+        return false;
+      }
+    });

    methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id);
    methodChannel.setMethodCallHandler(this);

    applySettings((Map<String, Object>) params.get("settings"));

    if (params.containsKey(JS_CHANNEL_NAMES_FIELD)) {
      registerJavaScriptChannelNames((List<String>) params.get(JS_CHANNEL_NAMES_FIELD));
    }

    if (params.containsKey("initialUrl")) {
      String url = (String) params.get("initialUrl");
      webView.loadUrl(url);
    }
  }

  @Override
  public View getView() {
    return webView;
  }

  @Override
  public void onMethodCall(MethodCall methodCall, Result result) {
    switch (methodCall.method) {
      case "loadUrl":
        loadUrl(methodCall, result);
        break;
      case "updateSettings":
        updateSettings(methodCall, result);
        break;
      case "canGoBack":
        canGoBack(methodCall, result);
        break;
      case "canGoForward":
        canGoForward(methodCall, result);
        break;
      case "goBack":
        goBack(methodCall, result);
        break;
      case "goForward":
        goForward(methodCall, result);
        break;
      case "reload":
        reload(methodCall, result);
        break;
      case "currentUrl":
        currentUrl(methodCall, result);
        break;
      case "evaluateJavascript":
        evaluateJavaScript(methodCall, result);
        break;
      case "addJavascriptChannels":
        addJavaScriptChannels(methodCall, result);
        break;
      case "removeJavascriptChannels":
        removeJavaScriptChannels(methodCall, result);
        break;
      default:
        result.notImplemented();
    }
  }

  private void loadUrl(MethodCall methodCall, Result result) {
    String url = (String) methodCall.arguments;
    webView.loadUrl(url);
    result.success(null);
  }

  private void doJavascriptRedirect(MethodCall methodCall, Result result) {
    String url = (String) methodCall.arguments;
    webView.loadUrl(url);
    result.success(null);
  }

  private void canGoBack(MethodCall methodCall, Result result) {
    result.success(webView.canGoBack());
  }

  private void canGoForward(MethodCall methodCall, Result result) {
    result.success(webView.canGoForward());
  }

  private void goBack(MethodCall methodCall, Result result) {
    if (webView.canGoBack()) {
      webView.goBack();
    }
    result.success(null);
  }

  private void goForward(MethodCall methodCall, Result result) {
    if (webView.canGoForward()) {
      webView.goForward();
    }
    result.success(null);
  }

  private void reload(MethodCall methodCall, Result result) {
    webView.reload();
    result.success(null);
  }

  private void currentUrl(MethodCall methodCall, Result result) {
    result.success(webView.getUrl());
  }

  @SuppressWarnings("unchecked")
  private void updateSettings(MethodCall methodCall, Result result) {
    applySettings((Map<String, Object>) methodCall.arguments);
    result.success(null);
  }

  private void evaluateJavaScript(MethodCall methodCall, final Result result) {
    String jsString = (String) methodCall.arguments;
    if (jsString == null) {
      throw new UnsupportedOperationException("JavaScript string cannot be null");
    }
    webView.evaluateJavascript(
        jsString,
        new android.webkit.ValueCallback<String>() {
          @Override
          public void onReceiveValue(String value) {
            result.success(value);
          }
        });
  }

  @SuppressWarnings("unchecked")
  private void addJavaScriptChannels(MethodCall methodCall, Result result) {
    List<String> channelNames = (List<String>) methodCall.arguments;
    registerJavaScriptChannelNames(channelNames);
    result.success(null);
  }

  @SuppressWarnings("unchecked")
  private void removeJavaScriptChannels(MethodCall methodCall, Result result) {
    List<String> channelNames = (List<String>) methodCall.arguments;
    for (String channelName : channelNames) {
      webView.removeJavascriptInterface(channelName);
    }
    result.success(null);
  }

  private void applySettings(Map<String, Object> settings) {
    for (String key : settings.keySet()) {
      switch (key) {
        case "jsMode":
          updateJsMode((Integer) settings.get(key));
          break;
        default:
          throw new IllegalArgumentException("Unknown WebView setting: " + key);
      }
    }
  }

  private void updateJsMode(int mode) {
    switch (mode) {
      case 0: // disabled
        webView.getSettings().setJavaScriptEnabled(false);
        break;
      case 1: // unrestricted
        webView.getSettings().setJavaScriptEnabled(true);
        break;
      default:
        throw new IllegalArgumentException("Trying to set unknown JavaScript mode: " + mode);
    }
  }

  private void registerJavaScriptChannelNames(List<String> channelNames) {
    for (String channelName : channelNames) {
      webView.addJavascriptInterface(
          new JavaScriptChannel(methodChannel, channelName), channelName);
    }
  }

  @Override
  public void dispose() {}
}

step3:- copy updated plugin in your project and update path in pubspec.yaml like this

webview_flutter:
path: webview_flutter

Note:- webview_flutter is the plugin folder inside the apps root directory /myapp/webview_flutter
step4:- compile

@rakeshlanjewar
Copy link

PS. server side redirects are working

@rakeshlanjewar
Copy link

@zoechi can i make a pull request regarding this ?
What you say ?

@zoechi
Copy link
Contributor

zoechi commented Feb 12, 2019

@rakeshlanjewarwork sure, go ahead 👍

@rakeshlanjewar
Copy link

thanks , pushing...

@zxl777
Copy link

zxl777 commented Feb 20, 2019

@rakeshlanjewarwork We are waiting for your pull request, thank you.

@rakeshlanjewar
Copy link

rakeshlanjewar commented Feb 20, 2019

i have made a pull request on same day. flutter/plugins#1197
but cant pass the tests because of file formatting, can you guide me how to format the java files.

@zxl777
Copy link

zxl777 commented Feb 20, 2019

Could you try VS CODE - Command - Format Document ?

@realcarlos
Copy link

realcarlos commented Mar 15, 2019

@rakeshlanjewarwork I also need this fix , could you try again ? Thank you very much.

@rakeshlanjewar
Copy link

@realcarlos I have tried to pull request but due to some problems about formatting of code the CI build is failing.

If you can make a pull please see here flutter/plugins#1243

@phaniteja1
Copy link

Need this fix badly!

@realcarlos
Copy link

@zoechi could you Kindly help to merge it? thank you

@Smarto-Dev
Copy link

Smarto-Dev commented Jun 24, 2019

@zoechi @ffeu facing same issue, white blank screen on ios

@brampersandon
Copy link

Hi all, I just ran into this same issue, and it looks like the underlying issue is that these are redirects from HTTP to HTTPS. On iOS, for example, we have to add these domains to our App Transport Security exception list (e.g.: https://stackoverflow.com/questions/30731785/how-do-i-load-an-http-url-with-app-transport-security-enabled-in-ios-9)

@pedrosalesmiranda
Copy link

@skylineproject same issue here (just tested on Android) can anyone tell me what they did to fix?
I tried @rakeshlanjewarwork solution but without success (file was not exactly has described here not sure if that is the problem) ... any help would be great thanks.

@amirh
Copy link
Contributor

amirh commented Jul 23, 2019

I just tested redirects with webview_flutter 0.3.10+3 and it's working for me.

I tested on Android O and Android M devices (to cover both the WebViewClientCompat and WebViewClient code paths), and on an iOS device.

Loading https://flutter.io which redirects to https://flutter.dev works for me on both Android and iOS.

As @skylineproject mentioned in #25351 (comment) iOS is not allowing http connections by default, but you can add an Info.plist key to enable it. With the Info.plist key loading http://flutter.io which redirects to https://flutter.dev worked on all tested devices.

@pedrosalesmiranda which webview_flutter version are you using? which device and OS version? can you share a sample url that's not loading for you?

@amirh amirh added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jul 23, 2019
@pedrosalesmiranda
Copy link

My bad here. I tought ^0.1.1 was getting the last version of minor but nop. So i just changed .yaml to webview_flutter: 0.3.10+3
and redirects are working now. I just have problem with loading images now but i will research first to see what i find out. Thank you @amirh

@amirh
Copy link
Contributor

amirh commented Jul 23, 2019

Great, I'm closing this issue then.
If someone still sees a problem with redirect please reopen.

@amirh amirh closed this as completed Jul 23, 2019
@mavr301
Copy link

mavr301 commented Aug 13, 2019

Hi all, I do not know if my issue related to redirections, problem is that I can not open simple html page on my server which is not HTTPS (for example http://<MY_IP_ADDRESS>/stats.html) but it can be opened in browser. Also I've tested example on Android https://github.com/flutter/plugins/tree/master/packages/webview_flutter/example it's also not work with initial URL 'http://google.com'

@AliSayed
Copy link

@mavr301 to load http sites on iOS

you need to add new key to ios/Runner/Info.plist
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSAllowsArbitraryLoadsInWebContent</key> <true/> </dict>

@piyushsinha24
Copy link

https://www.pleatsbouttique.com
This still shows white screen and fails to redirect. I tried 0.3.10+3 still no luck :/

@woutervanwijk
Copy link

@mavr301 to load http sites on iOS

you need to add new key to ios/Runner/Info.plist
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSAllowsArbitraryLoadsInWebContent</key> <true/> </dict>

Worked for me, thx!

@myriky
Copy link

myriky commented Mar 17, 2020

I'm using webview_flutter 0.3.18+1

if url has 302 redirect android will be shown Webpage not available.

net::ERR_UNKNOWN_URL_SCHEME

https://forms.gle/UYTCutLKbSGdDUw99
=> https://docs.google.com/forms/d/e/1FAIpQLSdPjIjDbhSKiF5z8mVfosk9Z0wql9_-CnwZxnaXehWbgPckyg/viewform?usp=send_form

Not everything doesn't work.
especially if it is 302 responses in HTTP/2.

here is CURL exceute result

$ curl -I https://forms.gle/UYTCutLKbSGdDUw99
HTTP/2 302
cache-control: no-cache, no-store, max-age=0, must-revalidate
content-security-policy: script-src 'nonce-Q2Wa/q0LgbuqorGQEegIoQ' 'unsafe-inline';object-src 'none';base-uri 'self';report-uri /_/DurableDeepLinkUi/cspreport;worker-src 'self'
content-type: application/binary
expires: Mon, 01 Jan 1990 00:00:00 GMT
location: https://docs.google.com/forms/d/e/1FAIpQLSdPjIjDbhSKiF5z8mVfosk9Z0wql9_-CnwZxnaXehWbgPckyg/viewform?usp=send_form
pragma: no-cache
server: ESF
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 0
accept-ranges: bytes
accept-ranges: bytes
date: Tue, 17 Mar 2020 13:06:08 GMT
x-served-by: cache-tyo19949-TYO
x-cache: MISS
x-cache-hits: 0
x-timer: S1584450368.985180,VS0,VE310
vary: x-fh-requested-host, accept-encoding
content-length: 0

any idea? thank you :)

@lock
Copy link

lock bot commented Apr 2, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@lock lock bot locked and limited conversation to collaborators Apr 2, 2020
@pedromassangocode pedromassangocode removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Feb 5, 2021
@flutter-triage-bot flutter-triage-bot bot added the package flutter/packages repository. See also p: labels. label Jul 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: new feature Nothing broken; request for a new capability p: webview The WebView plugin package flutter/packages repository. See also p: labels.
Projects
None yet
Development

No branches or pull requests