Cordova : How to diagnose ajax not working for UWP

2020-07-18 04:39发布

问题:

I have a simple Cordova application, where when built, and running as a Windows UWP application, has ajax calls are somehow being blocked my work network.

I have asked this many times before, but thought would try to reword, as have never got any solutions.

The application ajax calls work fine on my home machine, or whats seems to be most other networks. When it works, I can see all the output in Wireshark

When on my work machine, connected to our work Network, I see absolutely nothing in Wireshark. If I point to a server running on localhost, the app does work (but I see nothing in Wireshark, but perhaps this is because it is localhost)

If I run the app outside of the UWP container, ie I just run on the same machine, on the same network, but via the desktop browser (as you do for Cordova to debugging), it also works fine.

So it appears to be blocked before it even gets to the Network, as we see nothing in Wireshark at all, so this rules out host not reachable, CORS etc as it hasn't even been sent to the server.

I can run this in debug via Visual Studio, and I run the following test code...

document.addEventListener('deviceready', callUrl, false);

function callUrl() {

  console.log('callUrl'); 
  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function () {
    var DONE = 4; // readyState 4 means the request is done.
    var OK = 200; // status 200 is a successful return.
    console.log(xhr.readyState);
    if (xhr.readyState === DONE) {
      if (xhr.status === OK)
        console.log(xhr.responseText); // 'This is the returned text.'
    } else {
      console.log('Error: ' + xhr.status); // An error occurred during the request.
    }
  }

  xhr.open('GET', 'https://httpbin.org/get');
  xhr.send(null);         

};

onreadystatechangeis called twice, with xhr.readyState first 2 and then 4. status is always 0.

How can I diagnose what is blocking this?? I have absolutely no idea. This is something low level, but how to see what? I have also looked through Windows Event logs, but can find nothing.

The Ajax call just returns 0 with a blank description. Our Network administrator just says there is something wrong with my app (I have tried multiple Cordova apps, including just basic test apps)

Thanks in advance for any help.

[EDIT1]

In response to the comment from @Xavier, all I have in my AppxManifest.xml (that I extracted from my built .appxupload file) is

<Capabilities> 
  <Capability Name="internetClient" /> 
</Capabilities> 

There is some documentation on the capabilities here, where we have the following (right at the bottom of the page)..

    The following capabilities are unavailable when deploying your Remote Mode application to the Windows Store:

    Enterprise Authentication (enterpriseAuthentication)
    Shared User Certificates (sharedUserCertificates)
    Documents Library (documentsLibrary)
    Music Library (musicLibrary)
    Pictures Library (picturesLibrary)
    Videos Library (videosLibrary)
    Removable Storage (removableStorage)
    Internet client/server (internetClientServer) - note that internetClient is still permitted
    Private network client/server (privateNetworkClientServer)

I am not sure were we even set these in Visual Studio (config.xml), but also the above seems to be saying some of these can't be used?

Should the internetClient be enough (I only want to call out to a server as a client, not act as a server).

Also, this seems to be enough to work on most Networks except for my Work..

[EDIT2]

In response to the reply on the CSP...

There is a discussion on this here. The test Cordova app I created in Visual Studio does have this :

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

Surprisingly, I don't see this in my Ionic index.html, but perhaps this is because it is using the white list plugin?

My Ionic application has the following in the config.xml

  <access origin="*" />
  <allow-intent href="http://*/*" />
  <allow-intent href="https://*/*" />
  <allow-intent href="tel:*" />
  <allow-intent href="sms:*" />
  <allow-intent href="mailto:*" />
  <allow-intent href="geo:*" />
  <allow-navigation href="http://localhost:8080/*" />
  ....
  <plugin name="cordova-plugin-whitelist" spec="^1.3.1" />

It would be great if the ajax even had some error saying it was something to do with CSP if that is what it is, but we just get nothing.

Once again, it is weird that the problem only occurs on my work network (either on cable or our WIFI). If I run the exact machine (e.g. a Surface tablet)over another connection (e.g. tether it to my phones cell), then all works as expected. So it must be some setting to do with the network (or firewall maybe), which also I find strange as surely I would at least then see something in Wireshark.

Would be great to be able to "debug into" the ajax call, and see where it is failing.

[EDIT 3]

After reading one of the comments, I used fiddler to see if I could see anything, which I do...

It even reports 200 (which is not correct), my request still fails.

回答1:

According to this, you need to request the privateNetworkClientServer capability in order to communicate with a local network.

Note that this capability only works if you app is configured for local mode (your app will be rejected from the store if using this capability in remote mode).

To enable local mode, you need to set <preference name="WindowsDefaultUriPrefix" value="ms-appx://" /> in your cordova config.xml.

Note that local mode might lead to other issues, as you cannot use e.g. inline scripts in local mode (CSP violation)