pichillilorenzo / flutter_inappwebview

A Flutter plugin that allows you to add an inline webview, to use a headless webview, and to open an in-app browser window.
https://inappwebview.dev
Apache License 2.0
3.28k stars 1.61k forks source link

iOS: Ajax calls being blocked if useShouldInterceptAjaxRequest: true #282

Closed renedecandido closed 4 weeks ago

renedecandido commented 4 years ago

Environment

Flutter version: v1.12.13+hotfix.7, on Mac OS X 10.14.6 18G95, locale en-GB Plugin version: master branch iOS version: 12.3.1 Xcode version: 11.3
Device information: iPad Air

Description

Ajax calls should be intercept-able but should "go through" after being logged. Works as expected on Android, but not on iOS

Steps to reproduce

  1. set useShouldInterceptAjaxRequest to true
  2. set javaScriptEnabled to true
  3. print() request details in shouldInterceptFetchRequest
  4. Click on the "Get external Content" button on the w3schools website

Gist with the current implementation using InAppWebView

timtasay commented 2 years ago

@renedecandido I also have this issue when enable useShouldInterceptAjaxRequest=true. We found it out because Adobe Analytic does not trigger after useShouldInterceptAjaxRequest is set to true. I can intercept ajax requests using onAjaxProgress and other methods fine but it does not forward the ajax request to the server making the Adobe Analytic tool not firing. This only happens in iOS. Android works perfectly fine. The workaround is to override XmlHttpRequest with JavaScript while we are waiting for the fix. See code below.

ajaxoverride.js

var open = window.XMLHttpRequest.prototype.open,
    send = window.XMLHttpRequest.prototype.send,
    onReadyStateChange;

var ajaxUrl = '';

// Override the XmlHttpRequest.open() method to track request URL.
function openReplacement(method, url, async) {
    // Track ajaxUrl to use in onReadyStateChagneReplacement 
    ajaxUrl = url;
    return open.apply(this, arguments);
}

// Override the XmlHttpRequest.send() method to define custom method and apply
// any changes necessary.
function sendReplacement(data) {
    if (this.onreadystatechange) {
        this._onreadystatechange = this.onreadystatechange;
    }
    this.onreadystatechange = onReadyStateChangeReplacement;
    return send.apply(this, arguments);
}

// Override onReadyStateChange to check for cart refresh. If cart refresh triggers,
// call ajaxRequestHandler in the Flutter code define in the InAppWebview controller.
function onReadyStateChangeReplacement() {
    if (this.readyState === XMLHttpRequest.DONE) {
        if (this.responseText !== "" && this.responseText !== null) {
            if (ajaxUrl === "Whatever you want") {
                var oData = JSON.stringify({ 'data': this.responseText });
                window.flutter_inappwebview.callHandler('ajaxRequestHandler', { paramData: oData }).then(function (result) {
                })
            }
        }
    }
    if (this._onreadystatechange) {
        return this._onreadystatechange.apply(this, arguments);
    }
}
window.XMLHttpRequest.prototype.open = openReplacement;
window.XMLHttpRequest.prototype.send = sendReplacement;

In Flutter add this code.

InAppWebView(
...
              onLoadStop: (controller, url) async {
                  if (http.Platform.isIOS) {
                    await controller.injectJavascriptFileFromAsset(
                        assetFilePath: "assets/js/ajaxoverride.js");
                    controller.addJavaScriptHandler(
                        handlerName: 'ajaxRequestHandler',
                        callback: (params) {
                          // Logic here
                        });
                  }
               }
...
)
github-actions[bot] commented 4 weeks ago

This issue is stale and has been automatically closed because it has been open for more than 365 days with no activity. Please reopen a new issue if you still have it.

github-actions[bot] commented 2 weeks ago

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 and a minimal reproduction of the issue.