React Native:Android WebView为某些网站和某些设备返回空白屏幕

时间:2017-05-16 06:05:08

标签: android networking https react-native android-webview

我使用WebView指向HTTPS站点已经有一个有效的反应原生应用程序已经有好几个月了。 这一切都运行良好,但突然WebView开始返回空白页而不是HTTPS站点。

通过调试,我发现了:

  • 这种情况只发生在我的设备上(我的用户没有报告此问题)

  • 某些网站会返回空白屏幕,对于某些网站,它会正确呈现。 (例如,google.com会呈现,而amazon.com会返回一个空白屏幕)

  • 通过调试Chrome检查器中的WebView,似乎每次对其中一个站点(例如amazon.com)进行GET调用时,呼叫在1秒左右后就会被取消。

    < / LI>
  • 在我的android-chrome浏览器上调用,打开和渲染这些网站。

似乎我的设备中的某些内容阻止了WebView中的某些网站,可能是设置或应用。它可能是什么?

我正在使用LG G4,尝试使用API​​版本19和23。

3 个答案:

答案 0 :(得分:2)

必须是因为开发模式下的私有SSL错误。如果您将看到控制台登录调试模式,那么您可以看到一行说 Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

如果是,那么只需添加一个在文档中没有提到的新道具。道具是ignoreSslError={true},即使出现SSL错误,它也会强制WebView加载网站。

前 - <WebView ignoreSslError={true} source={{uri: 'https://www.google.com'}} />

来源:https://github.com/facebook/react-native/pull/9680

答案 1 :(得分:0)

这对我有用。

对我来说,很明显我的证书不受信任。在我的情况下,可以通过在配置错误的服务器本身上添加缺少的中间证书来解决此问题。不幸的是,由于我没有所需的访问权限,因此我决定查看是否有可能实施替代方法。

  • 最终,我按照以下说明添加了网络安全配置文件并配置了自定义CA:{​​{3}}

以下是详细信息:

  • 我的路看起来像 创建必要的文件夹后,/project_root/android/app/src/main/res/xml/network_security_config.xml。

文件内容如下所示:

;with Product as (
    select * from (
        VALUES 
(1, '2018-12-25','2019-01-05' ),
(1, '2019-03-01','2019-03-10' ),
(1, '2019-03-15','2019-03-19' ),
(1, '2019-03-22','2019-03-28' ),
(1, '2019-03-30','2019-04-02' ),
(1, '2019-04-10','2019-04-15' ),
(1, '2019-04-18','2019-04-25' )
    ) as a1 (ProductId   ,ProductStartDt   ,ProductEndDt)
), OrderedProduct as (
    select *, ROW_NUMBER() over (order by ProductStartDt) as RowNum
    from Product
), DateGroupsInterim (RowNum, GroupNum, GrpStartDt) as (
    select RowNum, 1, ProductEndDt
    from OrderedProduct
    where RowNum=1
    union all 
    select OrderedProduct.RowNum, 
        CASE WHEN OrderedProduct.ProductStartDt <= dateadd(day, 15, dgi.GrpStartDt) 
                THEN dgi.GroupNum 
                ELSE dgi.GroupNum + 1
        END,
        CASE WHEN OrderedProduct.ProductStartDt <= dateadd(day, 15, dgi.GrpStartDt) 
                THEN dgi.GrpStartDt 
                ELSE OrderedProduct.ProductEndDt
        END
    from DateGroupsInterim dgi
        join OrderedProduct on OrderedProduct.RowNum=dgi.RowNum+1
) select OrderedProduct.ProductId, OrderedProduct.ProductStartDt, OrderedProduct.ProductEndDt, DateGroupsInterim.GroupNum as GroupNo
from DateGroupsInterim
    JOIN OrderedProduct on OrderedProduct.RowNum = DateGroupsInterim.RowNum;

在上面的代码示例中,我替换了问题域中的“ example.com”。

  • 接下来,我在Web浏览器中打开问题域,并将证书下载到我的计算机上。

在Mac上的Chrome中,单击域旁边的锁定图标,然后在“证书”上单击并将证书图标拖到本地目录。这将传输DER编码的二进制文件。

在Windows上的Chrome中,您单击域旁边的锁定图标,然后单击“证书”,然后单击“详细信息”选项卡,最后单击右下角的“复制到文件”。导出时选择DER版本。

  • 对于下一步,我发现我需要使用OpenSSL。

要检查是否已安装

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

如果失败,您可以通过以下方式将其安装在Mac上

openssl version

有关Windows的说明,请点击此处:https://developer.android.com/training/articles/security-config

  • 在准备好OpenSSL之后,在“终端/ CLI”窗口中,我使用以下命令将文件转换为PEM:
brew install openssl
  • 在创建必要的文件夹后,我将生成的my_ca.pem移至了/project_root/android/app/src/main/res/raw/my_ca.pem。

  • 最后在/project_root/android/app/src/main/AndroidManifest.xml中,我将android:networkSecurityConfig =“ @ xml / network_security_config”添加到类似于以下内容的application元素:

openssl x509 -in downloaded_cert.cer -inform DER -out my_ca.pem -outform PEM

答案 2 :(得分:0)

哦,是的,它运行成功。

<View style={{ height: 150, width: 150,overflow:'hidden' }}>
            <WebView
              source={{ uri: 'https://github.com/facebook/react-native' }}
              scalesPageToFit={true}
            />
</View>