Home > Mobile >  Fetch and XHR Request working on Android but not on iOS
Fetch and XHR Request working on Android but not on iOS

Time:12-25

I've been developing an application using Cordova that's intended to run on mobile devices, both iOS and Android. Part of the application involves making a POST request to a server, which I originally implemented using an XHR request. It succesfuly sends the data and gets the answer from the server, however when running the same application on an iOS both physical device or emulator, the request returns 0 with a null body, as if it's not sent.

I switched to using the fetch-api in an attempt to get more information, and now I receive:

TypeError: Load failed

An error I haven't been able to find with that specific wording.

On android, the fetch-api completed succesfully, with a correct response from the server.

My server does have SSL, and I'm sending the request through HTTPS. I've also checked the security policy which I'm not too familiar with, but I'm using the following (hiding my server's url):

 <meta http-equiv="Content-Security-Policy" content="default-src 'unsafe-inline' * 'self' server.url.com data: gap: https://ssl.gstatic.com 'unsafe-inline' 'unsafe-eval' ws: wss:; style-src 'self' 'unsafe-inline'; media-src *">

I've also added the following to my Info.plist:

       <dict>
                <key>NSExceptionDomains</key>
                <dict>
                    <key>https://server.url.com/key>
                    <dict>
                        <key>NSIncludesSubdomains</key>
                        <true/>
                        <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                        <true/>
                        <key>NSTemporaryExceptionMinimumTLSVersion</key>
                        <string>TLSv1.1</string>
                    </dict>
                </dict>
            </dict>
        <dict>

Lastly, I've also added the domain using the whitelist plugin.

The javascript code sending the post is the following:

let requestOptions = {
    method: 'POST',
    mode: cors,
    credentials: 'same-origin',
    cache: 'no-cache',
    redirect: 'follow',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(out_data)
};

fetch(url, requestOptions)
        .then(async response => {
            const isJson = response.headers.get('content-type').includes('application/json');
            const data = isJson && await response.json();

            if (!response.ok) {
                console.log(response.status);
                const error = (data && data.message) || response.status;
                alert("Request denied with error "   response.status.toString()) 
                return Promise.reject(error)
            }
            console.log(response.status);
            console.log(JSON.stringify(data));
        })
        .catch(error => {
            console.error("There was an error!", error);
            alert(error);
        });

CodePudding user response:

You could use cordova-plugin-ios-xhr instead and set your preferences to

<preference name="AllowUntrustedCerts"  value="true" />
<preference name="InterceptRemoteRequests" value="all" />

Solves a lot of issues with XHR and iOS

  • Related