Cordova发布版中的AJAX调用失败

7
我正在为Android开发一个Cordova应用程序,并且在jQuery ajax调用方面遇到了奇怪的问题:调试版本没有问题,而发布版本每个ajax调用都会失败并显示错误。如果我通过USB在设备上运行,一切正常。如果我编译应用程序为调试模式,并将其复制和安装在设备上,那么一切正常。
如果我将应用程序编译为发布模式,并使用jarsigner和zipalign进行签名和优化,并将其复制和安装在设备上,则相同的ajax调用将以readyState 0,responseText为空,status 0和statusText“error”的形式失败。
我花了一周的时间在StackOverflow和谷歌上搜索并尝试所有类似的问题,但什么也没有改变。这个主题与我的SSL证书相似,但没有提供其他解决方案:Ajax calls fail when running Android Cordova app in Release mode Cordova版本是6.5(但我在6.4中也遇到了此问题)。
以下是应用程序中的ajax调用代码:
glang = window.localStorage.getItem('glang');

show_loader();

$.support.cors=true;
$.ajax({
  url: "https://app.laureatedesign.com/wp-content/plugins/designnews/ajax_langs.php",
  data: "act=aj_app_lng_lst&lang="+glang+"&xend=x",
  type: "POST",
  dataType: "json",
  timeout: 10000,
  success: function(results) {
      if (results["TYPE"]=="OK") {
          $('#main').html(results["CONTENT"]);
          $('#main').imagesLoaded( { },
            function() {
              show_content();
            }
          );
      }
      if (results["TYPE"]=="ERR") {
          show_error();
      }
      },
  error: function(XMLHttpRequest, status) {
     console.log(status);
     switch(status) {
      default:
          show_error();
       break;
      case "timeout":
          show_error();
       break;
     }
  }
});

可以将服务器上的ajax文件ajax_langs.php简化如下:

<?php
  $res = array("TYPE"=>"OK", "CONTENT"=>"Test");

  header('Access-Control-Allow-Origin: *');
  header('Access-Control-Allow-Methods: GET, POST');
  echo json_encode($res);
?>

这是我的config.xml文件:

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.naba.designnews" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>APPTITLE</name>
    <description>
        DESCRIPTION
    </description>
    <author email="EMAIL" href="WEBSITE">
        AUTHOR
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser" />
    <plugin name="InAppBrowser" value="CDVInAppBrowser" />
    <allow-navigation href="*" />
    <allow-navigation href="*://*youtube.com" />
    <access origin="*" />
    <access origin=".*" />
    <access origin="*.pushwoosh.com" />
    <access origin="http://*" />
    <access origin="https://*" />
    <access origin="https://laureatedesign.com" subdomains="true" />
    <allow-intent href="http://*" />
    <allow-intent href="https://*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <preference name="windows-target-version" value="10.0" />
    <preference name="StatusBarOverlaysWebView" value="false" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
</widget>

我添加了白名单插件。 在index.html文件中,我有这个meta标签:
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src * 'self' 'unsafe-inline'; script-src * 'self' 'unsafe-inline'; connect-src * https: http:">

我尝试删除并重新添加Android平台,但没有变化。
正如我在调试模式中所说,一切都很好,所有的ajax调用都返回成功。为了在Google Play上发布应用程序,我按照以下步骤进行签名和创建包:
1)cordova build android --release 2)jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore "PATH-TO-APP/APP.keystore" "PATH-TO-APP/platforms/android/build/outputs/apk/android-release-unsigned.apk" designnews
3)zipalign -v 4 "PATH-TO-APP/platforms/android/build/outputs/apk/android-release-unsigned.apk" "PATH-TO-APP/platforms/android/build/outputs/apk/AppTitle.apk"
我知道这是涉及CORS和跨域调用的问题。但为什么调试版本是好的,而发布版本不行呢?
请帮忙,谢谢。

这个问题解决了吗?你现在有解决方案了吗?我也遇到了同样的问题,但是在预检CORS检查中,readystate为4,状态为0。实际上,请求并没有到达服务器。 - J D
我的问题与ssl证书问题有关,由于一些链路问题。我的客户更新了它,然后一切都没问题了。 真正的痛苦是让他们接受他们的ssl不好...如果您无法连接到服务器,也许您应该尝试检查config.xml中的元内容安全内容和白名单声明。 - Marco Forlani
谢谢回复,我稍后会看一下。奇怪的是它只发生在某些设备上,比如Moto X Pure。 - J D
这很酷,但为什么在调试模式下没有发生呢? - dianikol
dianikol,我只能猜测调试模式在处理SSL问题时更加宽容... - Marco Forlani
我有同样的问题,有很多Android < 5.1设备都存在这个问题。 - Francesco
1个回答

2

我知道这是一个三年前的问题,但经过深入搜索,我找到了解决方案,并想要分享它。

我遇到了您所报告的同样问题,而解决方案非常简单:

1º - 您需要运行 "cordova prepare android" 命令以获取 Java 二进制文件。

2º - 在 Android Studio 中打开输出该命令的代码,导航至文件夹 manifests/AndroidManifest.xml

3º - 有一个名为 "application" 的元素,您只需添加 android:usesCleartextTraffic="true"

4º - 构建并签署您的应用程序,现在应该可以无任何问题地运行 ajax!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接