Is it possible to intercept post requests from WKWebView and get request body?

When developing an iOS application using Xamarin.iOS, we have a WKWebView that displays our own website inside.

We want to be able to intercept HTTP requests sent from the WKWebView's JS and extract the request body. Specifically for Form Post requests.

I know we can catch the URL for the requests using the WKNavigationDelegate, but is there a way to capture the whole request?

Thanks,
Andy

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    Firstly we need to notify this js post request on native, I find this post talking about this. Here is the js code:

    var s_ajaxListener = new Object();
    s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
    s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
    s_ajaxListener.callback = function () {
      // this.method :the ajax method used
      // this.url    :the url of the requested script (including query string, if any) (urlencoded) 
      // this.data   :the data sent, if any ex: foo=bar&a=b (urlencoded)
    }
    
    XMLHttpRequest.prototype.open = function(a,b) {
      if (!a) var a='';
      if (!b) var b='';
      s_ajaxListener.tempOpen.apply(this, arguments);
      s_ajaxListener.method = a;  
      s_ajaxListener.url = b;
      if (a.toLowerCase() == 'get') {
        s_ajaxListener.data = b.split('?');
        s_ajaxListener.data = s_ajaxListener.data[1];
      }
    }
    
    XMLHttpRequest.prototype.send = function(a,b) {
      if (!a) var a='';
      if (!b) var b='';
      s_ajaxListener.tempSend.apply(this, arguments);
      if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
      s_ajaxListener.callback();
    }
    

    In this callback method, we can pass the data to native. Two ways to achieve that:

    1. Define a method in our project, use js code to call this method and pass the data.
    2. Use window.location='SpecialUrlScheme://?' + this.data; this will open a new page in wkwebView. And you can handle this action using WKNavigationDelegate

    At last we need to inject this js to our WKWebView:

    // This file is what we defined above
    NSData scriptData = NSData.FromUrl(new NSUrl(NSBundle.MainBundle.PathForResource("JSFileName", "js"), false));
    NSString scriptContent = NSString.FromData(scriptData, NSStringEncoding.UTF8);
    var script = new WKUserScript(scriptContent, WKUserScriptInjectionTime.AtDocumentStart, true);
    WKWebViewConfiguration configuration = new WKWebViewConfiguration();
    configuration.UserContentController.AddUserScript(script);
    
    WKWebView webView = new WKWebView(new CGRect(0, 0, 320, 600), configuration);
    View.AddSubview(webView);
    
Sign In or Register to comment.