Search code examples
cordovapostwkwebviewinappbrowser

Form POST data is failing in WKWebview through cordova inappbrowser


I am using cordova inAppbrowser(v4.0.0) plugin to post data to external url. The form post is working fine in UIWebview, but it is failing with WKwebview. The post data are completely ignored.

let formContent = '<form action="' + URL + '" name=“myForm” id="myForm" method="post" target="secureiframe">';
    let element = document.createElement("div");
    let hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", “username”);
    hiddenField.setAttribute("value", “test”);
    element.appendChild(hiddenField);
    formContent += element.innerHTML;
    formContent += '</form>';
    let formContentUrl = 'data:text/html;base64,' + btoa(formContent);

let options = {location: 'no', usewkwebview: 'yes'}


var browser = this.inAppBrowser.create(formContentUrl, "_blank", options);


browser.on('loadstop').subscribe(event => {

       browser.executeScript({code:"document.getElementById('myForm').submit();"} );

 });

Solution

  • For some reason WKWebView is stripping-off the body in post request when the origin is null.

    The problem here is data-uri:

    let formContentUrl = 'data:text/html;base64,' + btoa(formContent);
    

    When you load this data url the origin would be set to opaque which is null and due to which WKWebView is stripping the post body.

    To resolve the issue, you could load the origin URL in WKWebView and in the 'loadstop' event you can construct the form, add it into the DOM and then trigger the submit event. This will ensure the origin is set and WKWebView will not strip-off the request body.

    Example code:

    constbrowser = this.iab.create('https://your-app-server-where-to-post-the-form', '_blank', options);
         
        browser.on('loadstop').subscribe((event) => {
        browser.executeScript({
        code:`
         var form = document.createElement("form");
         var element1 = document.createElement("input");
         var element2 = document.createElement("input");
         
         form.method = "POST";
         form.action = "your-form-action-route";
         
         element1.value="un";
         element1.name="un";
         form.appendChild(element1);
         
         element2.value="pw";
         element2.name="pw";
         form.appendChild(element2);
         
         document.body.appendChild(form);
         
         form.submit();
         `,
         });
         });