简体   繁体   中英

PhoneGap AJAX Calls NOT Working - December 2015

Cross posted here: http://community.phonegap.com/nitobi/topics/jquery-ajax-calls-all-of-the-sudden-do-not-work

This is a completely new bug as of the past week or two. Basically, I have an ajax call in the head of my index.html file in PhoneGap that errors out with a status code of 0. This was working as of ~2 weeks ago from this date (12/30/2015) and is suddenly not working. I have also confirmed that all AJAX calls are NOT working.

I have tried so many solutions and nothing is working.

I have tried:

  • meta http-equiv="Content-Security-Policy" content="default-src *; style-src * 'self' 'unsafe-inline' 'unsafe-eval'; script-src * 'self' 'unsafe-inline' 'unsafe-eval';">

  • Added $.support.cors = true;

  • Added Header set Access-Control-Allow-Origin "*" to the htaccess file on the server

  • Tried different versions of the whitelist plugin.

  • Tried different forms of access origin settings.

  • Tried moving inline JS from index.html into a separate JS file.

  • Verified that the line of code works both in localhost and from a different web server through Chrome.

Please help.

Here is my config.xml:

<?xml version="1.0" encoding="UTF-8" ?>
    <widget xmlns   = "http://www.w3.org/ns/widgets"
        xmlns:gap   = "http://phonegap.com/ns/1.0"
        id          = "xxxxxx"
        version     = "1.0.0" >

    <name>Test</name>
    <description>xxxx</description>
    <author href="xxxx" email="xxxx">xxxx</author>

    <!-- basic config -->

    <preference name='phonegap-version' value='cli-5.2.0' />
    <preference name="android-build-tool" value="ant" />

    <preference name="orientation"                value="portrait" />
    <!-- all: default means both landscape and portrait are enabled -->
    <preference name="fullscreen"                 value="false" />
    <!-- all: hides the status bar at the top of the screen -->
    <preference name="target-device"              value="universal" />
    <!-- ios: possible values handset, tablet, or universal -->
    <preference name="prerendered-icon"           value="true" />
    <!-- ios: if icon is prerendered, iOS will not apply it's gloss to the app's icon on the user's home screen -->
    <preference name="ios-statusbarstyle"         value="black-opaque" />
    <!-- ios: black-translucent will appear black because the PhoneGap webview doesn't go beneath the status bar -->
    <preference name="detect-data-types"          value="true" />
    <!-- ios: controls whether data types (such as phone no. and dates) are automatically turned into links by the system -->
    <preference name="exit-on-suspend"            value="false" />
    <!-- ios: if set to false, the splash screen must be hidden using a JavaScript API -->
    <preference name="disable-cursor"             value="false" />
    <!-- blackberry: prevents a mouse-icon/cursor from being displayed on the app -->


    <!-- START Splash Screen Config -->


    <!--<preference name="auto-hide-splash-screen" value="false" />
    <preference name="SplashScreenDelay" value="500000" />-->

    <gap:splash src="splash.png" />

    <!-- iPhone and iPod touch -->
    <gap:splash src="img/splash/Default.png" gap:platform="ios" width="320" height="480" />
    <gap:splash src="img/splash/Default@2x.png" gap:platform="ios" width="640" height="960" />

    <!-- iPhone 5 / iPod Touch (5th Generation) -->
    <gap:splash src="img/splash/Default-568h@2x.png" gap:platform="ios" width="640" height="1136" />

    <!-- iPhone 6 -->
    <gap:splash src="img/splash/Default-667h@2x.png" gap:platform="ios" width="750" height="1334" />
    <gap:splash src="img/splash/Default-Portrait-736h@3x.png" gap:platform="ios" width="1242" height="2208" />
    <gap:splash src="img/splash/Default-Landscape-736h@3x.png" gap:platform="ios" width="2208" height="1242" />

    <!-- iPad -->
    <gap:splash src="img/splash/Default-Portrait.png" gap:platform="ios" width="768" height="1024" />
    <gap:splash src="img/splash/Default-Landscape.png" gap:platform="ios" width="1024" height="768" />

    <!-- Retina iPad -->
    <gap:splash src="img/splash/Default-Portrait@2x.png" gap:platform="ios" width="1536" height="2048" />
    <gap:splash src="img/splash/Default-Landscape@2x.png" gap:platform="ios" width="2048" height="1536" />

    <!-- Android -->
    <gap:splash src="img/splash/port-ldpi.png" gap:platform="android" gap:qualifier="port-ldpi" />
    <gap:splash src="img/splash/land-ldpi.png" gap:platform="android" gap:qualifier="land-ldpi" />
    <gap:splash src="img/splash/port-mdpi.png" gap:platform="android" gap:qualifier="port-mdpi" />
    <gap:splash src="img/splash/land-mdpi.png" gap:platform="android" gap:qualifier="land-mdpi" />
    <gap:splash src="img/splash/port-hdpi.png" gap:platform="android" gap:qualifier="port-hdpi" />
    <gap:splash src="img/splash/land-hdpi.png" gap:platform="android" gap:qualifier="land-hdpi" />
    <gap:splash src="img/splash/port-xhdpi.png" gap:platform="android" gap:qualifier="port-xhdpi" />
    <gap:splash src="img/splash/land-xhdpi.png" gap:platform="android" gap:qualifier="land-xhdpi" />


    <!-- END Splash Screen Config -->

    <!-- allow background music play iOS -->
    <gap:config-file platform="ios" parent="UIBackgroundModes" overwrite="true">
      <array>    
             <string>audio</string>
      </array>
    </gap:config-file>

    <!-- enable permissions -->
    <preference name="permissions" value="none"/>
    <feature name="http://api.phonegap.com/1.0/file"/>
    <feature name="http://api.phonegap.com/1.0/geolocation"/>
    <feature name="http://api.phonegap.com/1.0/media"/>
    <feature name="http://api.phonegap.com/1.0/network"/>
    <feature name="http://api.phonegap.com/1.0/notification"/>

    <!-- Plugins -->
    <!--<plugin name="InAppBrowser" value="CDVInAppBrowser" />
    <feature name="InAppBrowser">
        <param name="ios-package" value="CDVInAppBrowser" />
    </feature>-->

    <!-- Core plugins -->
    <!--<gap:plugin name="org.apache.cordova.battery-status" />
    <gap:plugin name="org.apache.cordova.camera" />
    <gap:plugin name="org.apache.cordova.media-capture" />
    <gap:plugin name="org.apache.cordova.console" />
    <gap:plugin name="org.apache.cordova.contacts" />
    <gap:plugin name="org.apache.cordova.device-motion" />
    <gap:plugin name="org.apache.cordova.device-orientation" />
    <gap:plugin name="org.apache.cordova.dialogs" />
    <gap:plugin name="org.apache.cordova.file-transfer" />
    <gap:plugin name="org.apache.cordova.geolocation" />
    <gap:plugin name="org.apache.cordova.globalization" />
    <gap:plugin name="org.apache.cordova.inappbrowser" />
    <gap:plugin name="org.apache.cordova.network-information" />
    <gap:plugin name="org.apache.cordova.vibration" />-->

    <gap:plugin name="cordova-plugin-device" source="npm"/>
    <gap:plugin name="cordova-plugin-file" source="npm"/>
    <gap:plugin name="cordova-plugin-media" source="npm"/>
    <gap:plugin name="cordova-plugin-splashscreen" source="npm"/>
    <gap:plugin name="cordova-plugin-whitelist" source="npm"/>
    <gap:plugin name="cordova-plugin-x-socialsharing" source="npm"/>
    <gap:plugin name="cordova-plugin-admobpro" source="npm" spec="2.9.6"/>
    <!--<gap:plugin name="de.appplant.cordova.plugin.local-notification"/>-->

    <!-- Third party plugins -->
    <!-- A list of available plugins are available at https://build.phonegap.com/plugins -->
    <!--
    <gap:plugin name="com.phonegap.plugins.barcodescanner" />
    -->

    <!-- Define app icon for each platform. -->
    <!--<icon src="icon.png" />
    <icon src="res/icon/android/icon-36-ldpi.png"   gap:platform="android"    gap:density="ldpi" />
    <icon src="res/icon/android/icon-48-mdpi.png"   gap:platform="android"    gap:density="mdpi" />
    <icon src="res/icon/android/icon-72-hdpi.png"   gap:platform="android"    gap:density="hdpi" />
    <icon src="res/icon/android/icon-96-xhdpi.png"  gap:platform="android"    gap:density="xhdpi" />
    <icon src="res/icon/blackberry/icon-80.png"     gap:platform="blackberry" />
    <icon src="res/icon/blackberry/icon-80.png"     gap:platform="blackberry" gap:state="hover"/>
    <icon src="res/icon/ios/icon-57.png"            gap:platform="ios"        width="57" height="57" />
    <icon src="res/icon/ios/icon-72.png"            gap:platform="ios"        width="72" height="72" />
    <icon src="res/icon/ios/icon-57-2x.png"         gap:platform="ios"        width="114" height="114" />
    <icon src="res/icon/ios/icon-72-2x.png"         gap:platform="ios"        width="144" height="144" />
    <icon src="res/icon/webos/icon-64.png"          gap:platform="webos" />
    <icon src="res/icon/windows-phone/icon-48.png"  gap:platform="winphone" />
    <icon src="res/icon/windows-phone/icon-173.png" gap:platform="winphone"   gap:role="background" />-->
    <icon src="img/icons/apple-touch-icon.png" />
    <icon src="img/icons/apple-touch-icon-57x57-precomposed.png" gap:platform="ios" width="57" height="57"/>
    <icon src="img/icons/apple-touch-icon-72x72-precomposed.png" gap:platform="ios" width="72" height="72"/>
    <icon src="img/icons/apple-touch-icon-114x114-precomposed.png" gap:platform="ios" width="114" height="114"/>
    <icon src="img/icons/apple-touch-icon-144x144-precomposed.png" gap:platform="ios" width="144" height="144"/>
    <icon src="img/icons/apple-touch-icon-120x120-precomposed.png" gap:platform="ios" width="120" height="120"/>
    <icon src="img/icons/apple-touch-icon-76x76-precomposed.png" gap:platform="ios" width="76" height="76"/>
    <icon src="img/icons/apple-touch-icon-152x152-precomposed.png" gap:platform="ios" width="152" height="152"/>

    <!-- Define app splash screen for each platform. -->
    <!--  <gap:splash src="res/screen/android/screen-ldpi-portrait.png"  gap:platform="android" gap:density="ldpi" />
    <gap:splash src="res/screen/android/screen-mdpi-portrait.png"  gap:platform="android" gap:density="mdpi" />
    <gap:splash src="res/screen/android/screen-hdpi-portrait.png"  gap:platform="android" gap:density="hdpi" />
    <gap:splash src="res/screen/android/screen-xhdpi-portrait.png" gap:platform="android" gap:density="xhdpi" />
    <gap:splash src="res/screen/blackberry/screen-225.png"         gap:platform="blackberry" />
    <gap:splash src="res/screen/ios/screen-iphone-portrait.png"    gap:platform="ios"     width="320" height="480" />
    <gap:splash src="res/screen/ios/screen-iphone-portrait-2x.png" gap:platform="ios"     width="640" height="960" />
    <gap:splash src="res/screen/ios/screen-ipad-portrait.png"      gap:platform="ios"     width="768" height="1024" />
    <gap:splash src="res/screen/ios/screen-ipad-landscape.png"     gap:platform="ios"     width="1024" height="768" />
    <gap:splash src="res/screen/windows-phone/screen-portrait.jpg" gap:platform="winphone" />-->

    <!--
    Define access to external domains.

    <access />            - a blank access tag denies access to all external resources.
    <access origin="*" /> - a wildcard access tag allows access to all external resource.

    Otherwise, you can specify specific domains:
    -->
    <allow-navigation href="*"/>
    <allow-intent href="*"/>
    <access origin="*"/>
    <access origin="http://*.xxxxxxx/"/>
    <access origin="http://xxxxxx/"/>
    <!-- allow local pages -->
    <!--
    <access origin="http://phonegap.com" />                    - allow any secure requests to http://phonegap.com/
    <access origin="http://phonegap.com" subdomains="true" />  - same as above, but including subdomains, such as http://build.phonegap.com/
    -->

</widget>

Here is the script that is grabbing a page via AJAX:

<script>
        var dev_mode = true;

        if (dev_mode) {
            alert('Development Mode Active - You will see popups used for debugging purposes.');
            var scripts_url = 'http://dev.xxxxxxx/app/scripts';
        } else {
            var scripts_url = 'http://xxxxxxxxx/app/scripts';
        }

        jQuery.ajax({
            type : "POST",
            url : scripts_url,
            success: function(html) {
                jQuery('head').append(html);
            },
            error: function(xhr, status, err) {
                if (dev_mode) {
                    alert('error getting scripts: ' + status);
                    alert('error getting scripts: ' + err);
                    alert('error getting scripts: ' + xhr.responseText);
                    alert('error getting scripts: ' + xhr.status);
                    alert('error getting scripts: ' + xhr.statusText);
                    alert('error getting scripts: ' + JSON.stringify(xhr));
                }
            }
        });
    </script>

The AJAX call errors out with a status of 0.

Answers:

Is this your first App?

Not my first PhoneGap app, but my first really complex one.

What is your target platform and their target versions?

Targetting all platforms besides Blackberry (tested working on iOS, Android, and WP before this AJAX bug)

Are you using CLI, SDK or Build ?

Build

Not sure if it helps in your problem, but for someone else having similar issue, this may be helpful:

I had exact same issue a few weeks ago. My solution was to add the following to my server:

"Access-Control-Allow-Origin", "*";

"Access-Control-Allow-Headers", "X-Requested-With"

"Access-Control-Allow-Credentials", "X-Requested-With"

As I am using Express (NODE) server, I did by adding cors NPM package. And then, adding this before the server starts:

app.use(cors({credentials: true, origin: true}));

NOTE TO ALL: This app use an unrestricted whitelist filter, intended for development only.
THIS APP EXAMPLE IS INSECURE. IT IS UP TO YOU TO SECURE YOUR APP.
In addition, your app maybe reject by Google and Apple.


Thank you everyone for your help and I am glad to announce that I have fixed the issue. I am not 100% sure what fixed the issue as I have tried a number of solutions and I suspect that it was a little bit of everything. However, the first time I noticed the code actually work was when I removed the permissions line in the config.xml.

In summary, to fix the issue, I added:

  • CSP <meta http-equiv="Content-Security-Policy" content="default-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
  • Removed permissions and features from config.xml. (New Config below)
  • Waited for deviceready event before firing AJAX call

New Config.XML:

    <?xml version="1.0" encoding="UTF-8" ?>
    <widget xmlns   = "http://www.w3.org/ns/widgets"
        xmlns:gap   = "http://phonegap.com/ns/1.0"
        id          = "abc"
        version     = "1.0.0" >

    <name>abc</name>
    <description>abc</description>
    <author href="abc" email="abc">abc</author>

    <!-- basic config -->

    <preference name='phonegap-version' value='cli-5.2.0' />
    <preference name="android-build-tool" value="ant" />

    <preference name="orientation"                value="portrait" />
    <!-- all: default means both landscape and portrait are enabled -->
    <preference name="fullscreen"                 value="false" />
    <!-- all: hides the status bar at the top of the screen -->
    <preference name="target-device"              value="universal" />
    <!-- ios: possible values handset, tablet, or universal -->
    <preference name="prerendered-icon"           value="true" />
    <!-- ios: if icon is prerendered, iOS will not apply it's gloss to the app's icon on the user's home screen -->
    <preference name="ios-statusbarstyle"         value="black-opaque" />
    <!-- ios: black-translucent will appear black because the PhoneGap webview doesn't go beneath the status bar -->
    <preference name="detect-data-types"          value="true" />
    <!-- ios: controls whether data types (such as phone no. and dates) are automatically turned into links by the system -->
    <preference name="exit-on-suspend"            value="false" />
    <!-- ios: if set to false, the splash screen must be hidden using a JavaScript API -->
    <preference name="disable-cursor"             value="false" />
    <!-- blackberry: prevents a mouse-icon/cursor from being displayed on the app -->


    <!-- START Splash Screen Config -->


    <!--<preference name="auto-hide-splash-screen" value="false" />
    <preference name="SplashScreenDelay" value="500000" />-->

    <gap:splash src="splash.png" />

    <!-- iPhone and iPod touch -->
    <gap:splash src="img/splash/Default.png" gap:platform="ios" width="320" height="480" />
    <gap:splash src="img/splash/Default@2x.png" gap:platform="ios" width="640" height="960" />

    <!-- iPhone 5 / iPod Touch (5th Generation) -->
    <gap:splash src="img/splash/Default-568h@2x.png" gap:platform="ios" width="640" height="1136" />

    <!-- iPhone 6 -->
    <gap:splash src="img/splash/Default-667h@2x.png" gap:platform="ios" width="750" height="1334" />
    <gap:splash src="img/splash/Default-Portrait-736h@3x.png" gap:platform="ios" width="1242" height="2208" />
    <gap:splash src="img/splash/Default-Landscape-736h@3x.png" gap:platform="ios" width="2208" height="1242" />

    <!-- iPad -->
    <gap:splash src="img/splash/Default-Portrait.png" gap:platform="ios" width="768" height="1024" />
    <gap:splash src="img/splash/Default-Landscape.png" gap:platform="ios" width="1024" height="768" />

    <!-- Retina iPad -->
    <gap:splash src="img/splash/Default-Portrait@2x.png" gap:platform="ios" width="1536" height="2048" />
    <gap:splash src="img/splash/Default-Landscape@2x.png" gap:platform="ios" width="2048" height="1536" />

    <!-- Android -->
    <gap:splash src="img/splash/port-ldpi.png" gap:platform="android" gap:qualifier="port-ldpi" />
    <gap:splash src="img/splash/land-ldpi.png" gap:platform="android" gap:qualifier="land-ldpi" />
    <gap:splash src="img/splash/port-mdpi.png" gap:platform="android" gap:qualifier="port-mdpi" />
    <gap:splash src="img/splash/land-mdpi.png" gap:platform="android" gap:qualifier="land-mdpi" />
    <gap:splash src="img/splash/port-hdpi.png" gap:platform="android" gap:qualifier="port-hdpi" />
    <gap:splash src="img/splash/land-hdpi.png" gap:platform="android" gap:qualifier="land-hdpi" />
    <gap:splash src="img/splash/port-xhdpi.png" gap:platform="android" gap:qualifier="port-xhdpi" />
    <gap:splash src="img/splash/land-xhdpi.png" gap:platform="android" gap:qualifier="land-xhdpi" />


    <!-- END Splash Screen Config -->

    <!-- allow background music play iOS -->
    <gap:config-file platform="ios" parent="UIBackgroundModes" overwrite="true">
      <array>    
             <string>audio</string>
      </array>
    </gap:config-file>
<icon src="img/icons/apple-touch-icon.png" />
    <icon src="img/icons/apple-touch-icon-57x57-precomposed.png" gap:platform="ios" width="57" height="57"/>
    <icon src="img/icons/apple-touch-icon-72x72-precomposed.png" gap:platform="ios" width="72" height="72"/>
    <icon src="img/icons/apple-touch-icon-114x114-precomposed.png" gap:platform="ios" width="114" height="114"/>
    <icon src="img/icons/apple-touch-icon-144x144-precomposed.png" gap:platform="ios" width="144" height="144"/>
    <icon src="img/icons/apple-touch-icon-120x120-precomposed.png" gap:platform="ios" width="120" height="120"/>
    <icon src="img/icons/apple-touch-icon-76x76-precomposed.png" gap:platform="ios" width="76" height="76"/>
    <icon src="img/icons/apple-touch-icon-152x152-precomposed.png" gap:platform="ios" width="152" height="152"/>

    <gap:plugin name="cordova-plugin-device" source="npm"/>
    <gap:plugin name="cordova-plugin-file" source="npm"/>
    <gap:plugin name="cordova-plugin-media" source="npm"/>
    <gap:plugin name="cordova-plugin-splashscreen" source="npm"/>
    <gap:plugin name="cordova-plugin-whitelist" source="npm"/>
    <gap:plugin name="cordova-plugin-x-socialsharing" source="npm"/>
    <gap:plugin name="cordova-plugin-admobpro" source="npm" spec="2.9.6"/>

    <allow-navigation href="*"/>
    <allow-intent href="*"/>
    <access origin="*"/>

</widget>

New JS AJAX call:

document.addEventListener("deviceready", on_device_ready, false);
            function on_device_ready() {
                jQuery.ajax({
                    type : "GET",
                    url : scripts_url,
                    success: function(html) {
                        jQuery('head').append(html);
                    },
                    error: function(xhr, status, err) {
                        if (dev_mode) {
                            alert('error getting scripts: ' + status);
                            alert('error getting scripts: ' + err);
                            alert('error getting scripts: ' + xhr.responseText);
                            alert('error getting scripts: ' + xhr.status);
                            alert('error getting scripts: ' + xhr.statusText);
                            alert('error getting scripts: ' + JSON.stringify(xhr));
                        }
                    }
                });
            }

Thanks again everyone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM