当debuggable = false时,Phonegap跨域ajax请求仅在Android上失败,而不是在debuggable = true时失败

时间:2022-08-22 19:12:54

I've got a PhoneGap app that's working fine on iOS but when setup for a release build, does not work on Android.

我有一个在iOS上工作正常的PhoneGap应用程序,但是当设置发布版本时,在Android上不起作用。

I'm using the Phonegap CLI to create my application.

我正在使用Phonegap CLI来创建我的应用程序。

$ phonegap --version
4.2.0-0.24.2

The config.xml options for network access and whitelisting have been set:

已设置用于网络访问和白名单的config.xml选项:

<access origin="*" />
<feature name="http://api.phonegap.com/1.0/network" />

I've verified that my AndroidManifest.xml is requesting internet permission:

我已经验证我的AndroidManifest.xml正在请求互联网权限:

<uses-permission android:name="android.permission.INTERNET" />

My API returns the appropriate ACCESS-CONTROL-ALLOW-ORIGIN header value:

我的API返回相应的ACCESS-CONTROL-ALLOW-ORIGIN标头值:

Access-Control-Allow-Origin: *

For good measure I've also added this to my JS:

为了更好的衡量,我还将其添加到我的JS中:

$.support.cors = true;

If I set the android remote debugging attribute so that I can connect from chrome://inspect, then the network requests succeed and all is right with the world:

如果我设置android远程调试属性,以便我可以从chrome:// inspect连接,那么网络请求成功,所有这些都是正确的:

<application android:debuggable="true" ... >

However, if I simply remove that android:debuggable="true" so that I can submit to the play store, recompile, and test again, then my cross-domain ajax requests fail. When they fail, they're returning with jqXHR.status=0 and jqXHR.readyState=0, which in my experience indicates that the pre-flight OPTIONS request has failed for some reason.

但是,如果我只是删除android:debuggable =“true”以便我可以提交到Play商店,重新编译并再次测试,那么我的跨域ajax请求就会失败。当它们失败时,它们将返回jqXHR.status = 0和jqXHR.readyState = 0,根据我的经验,这表明飞行前的OPTIONS请求由于某种原因失败了。

Unfortunately, when I've enabled debugging and I connect to view the network requests, everything works -- so I can't see what might be wrong. I've restored to alert()-ing various things to try and figure out what's going on... but I'm not getting any further.

不幸的是,当我启用调试并连接以查看网络请求时,一切正常 - 所以我看不出可能出错的地方。我已经恢复警报() - 各种各样的东西,试图弄清楚发生了什么......但我没有得到任何进一步。

I can also run my application in a browser on my laptop using a file:// url (which is how it's opened in an Android app) as well as running it via a local webserver (at localhost:3030), and in both cases the cross-domain requests work completely fine.

我还可以使用file:// url(在Android应用程序中打开它的方式)在我的笔记本电脑上的浏览器中运行我的应用程序,以及通过本地网络服务器(在localhost:3030)运行它,在这两种情况下跨域请求工作完全正常。

I'm at a loss for what to do now. Is there something else I can alert to get more information about the error? (Maybe it's other headers causing the issue?)

我现在该做什么都不知所措。还有什么我可以提醒以获得有关错误的更多信息吗? (也许它是导致问题的其他标题?)

3 个解决方案

#1


1  

I believe I've found the issue: Android doesn't like one of my intermediate SSL certificates. This is consistent with the behavior that I've noted:

我相信我发现了这个问题:Android不喜欢我的中间SSL证书之一。这与我注意到的行为一致:

  • works fine on iOS
  • 适用于iOS

  • works fine in Chrome on laptop (file:// and localhost)
  • 适用于笔记本电脑上的Chrome(文件://和localhost)

  • works fine when using http://
  • 使用http://时工作正常

  • apparent CORS pre-flight request failure (statusCode=0, status=0) when using https://
  • 使用https://时明显的CORS飞行前请求失败(statusCode = 0,status = 0)

For now, I'll just be using non-SSL access to my api so I can move forward, and I'll let the server admin know there's something wrong with SSL ~ probably an intermediate cert that Android doesn't trust.

现在,我只是使用非SSL访问我的API,所以我可以继续前进,我会让服务器管理员知道SSL有问题〜可能是Android不信任的中间证书。

#2


1  

Yeah, it's definitely a certificate problem.

是的,这肯定是证书问题。

If you want to ignore the certificate error and continue loading you can do this:

如果要忽略证书错误并继续加载,可以执行以下操作:

yourCordovaWebView.setWebViewClient(new WebViewClient(){

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {

        handler.proceed();

    }

});

But doing that you remove all the security and become vulnerable to man in the middle attacks

但这样做可以消除所有安全性,并在中间攻击中变得容易受到攻击

You can inspect the SslError to see the real problem

您可以检查SslError以查看真正的问题

#3


1  

I had the same issue i.e. it works fine from desktop browser or android browser but does not work from phonegap app. It turns out that phonegap app is more strict about the certificate chain which you MUST set correctly in your webserver.

我有同样的问题,即它从桌面浏览器或Android浏览器工作正常,但无法从phonegap应用程序工作。事实证明,phonegap应用程序对您必须在您的网络服务器中正确设置的证书链更严格。

I use node.js for the webserver. So the correct way to set it should be:

我将node.js用于webserver。所以设置它的正确方法应该是:

sslOptions = {
    key: fs.readFileSync('/CertificateFolder/privkey.pem'),
    cert: fs.readFileSync('/CertificateFolder/cert.pem'),
    ca: fs.readFileSync('/CertificateFolder/chain.pem')
},
https = require('https').Server(sslOptions, app)

The key element here is "chain.pem" which if not added, the website will still work in web browser but not in phonegap app.

这里的关键元素是“chain.pem”,如果没有添加,网站仍将在网络浏览器中工作,但不在phonegap应用程序中。

#1


1  

I believe I've found the issue: Android doesn't like one of my intermediate SSL certificates. This is consistent with the behavior that I've noted:

我相信我发现了这个问题:Android不喜欢我的中间SSL证书之一。这与我注意到的行为一致:

  • works fine on iOS
  • 适用于iOS

  • works fine in Chrome on laptop (file:// and localhost)
  • 适用于笔记本电脑上的Chrome(文件://和localhost)

  • works fine when using http://
  • 使用http://时工作正常

  • apparent CORS pre-flight request failure (statusCode=0, status=0) when using https://
  • 使用https://时明显的CORS飞行前请求失败(statusCode = 0,status = 0)

For now, I'll just be using non-SSL access to my api so I can move forward, and I'll let the server admin know there's something wrong with SSL ~ probably an intermediate cert that Android doesn't trust.

现在,我只是使用非SSL访问我的API,所以我可以继续前进,我会让服务器管理员知道SSL有问题〜可能是Android不信任的中间证书。

#2


1  

Yeah, it's definitely a certificate problem.

是的,这肯定是证书问题。

If you want to ignore the certificate error and continue loading you can do this:

如果要忽略证书错误并继续加载,可以执行以下操作:

yourCordovaWebView.setWebViewClient(new WebViewClient(){

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {

        handler.proceed();

    }

});

But doing that you remove all the security and become vulnerable to man in the middle attacks

但这样做可以消除所有安全性,并在中间攻击中变得容易受到攻击

You can inspect the SslError to see the real problem

您可以检查SslError以查看真正的问题

#3


1  

I had the same issue i.e. it works fine from desktop browser or android browser but does not work from phonegap app. It turns out that phonegap app is more strict about the certificate chain which you MUST set correctly in your webserver.

我有同样的问题,即它从桌面浏览器或Android浏览器工作正常,但无法从phonegap应用程序工作。事实证明,phonegap应用程序对您必须在您的网络服务器中正确设置的证书链更严格。

I use node.js for the webserver. So the correct way to set it should be:

我将node.js用于webserver。所以设置它的正确方法应该是:

sslOptions = {
    key: fs.readFileSync('/CertificateFolder/privkey.pem'),
    cert: fs.readFileSync('/CertificateFolder/cert.pem'),
    ca: fs.readFileSync('/CertificateFolder/chain.pem')
},
https = require('https').Server(sslOptions, app)

The key element here is "chain.pem" which if not added, the website will still work in web browser but not in phonegap app.

这里的关键元素是“chain.pem”,如果没有添加,网站仍将在网络浏览器中工作,但不在phonegap应用程序中。