从android本机应用程序访问JS代码

从android本机应用程序访问JS代码,android,ajax,webview,cross-domain,Android,Ajax,Webview,Cross Domain,这似乎是一个奇怪的问题,但我很想知道它是否有效。我正在研究POC,因此必须证明或反驳这是否有效 Android应用程序中的用户界面将是本地的(Java+XML布局)+一些其他设备功能,如(摄像头/文件系统等) 我已经构建了一个JS库,它有一些函数可以执行Ajax post和get请求 在这个应用程序中,我有一个不可见的Webview,在这里我加载一个空白的HTML(引用这个JS库)。在这个WebView中,我注入了JavaScriptInterface。因此,从本质上讲,UI是本机的,您永远不会

这似乎是一个奇怪的问题,但我很想知道它是否有效。我正在研究POC,因此必须证明或反驳这是否有效

Android应用程序中的用户界面将是本地的(Java+XML布局)+一些其他设备功能,如(摄像头/文件系统等)

我已经构建了一个JS库,它有一些函数可以执行Ajax post和get请求

在这个应用程序中,我有一个不可见的Webview,在这里我加载一个空白的HTML(引用这个JS库)。在这个WebView中,我注入了JavaScriptInterface。因此,从本质上讲,UI是本机的,您永远不会看到Webview。这只是一个主机,它提供了对本机代码的JS库的访问

现在,在我的UI上的一些操作中,我调用Webview上的JS函数,它反过来尝试进行ajax调用(loadUrl调用例如javascipt:functionName()。但是,这些调用失败,没有任何可见错误

注意:如果我把这个HTML文件加载到我的桌面浏览器上,它也可以工作。AJAX调用成功

但是,当我通过JavascriptInterface(或webview.loadUrl()调用)启动Ajax调用时,它们失败,响应状态为0

不过,除了AJAX之外,简单的函数调用、警报和通过javascript接口的回调都可以很好地工作

Q:我知道这是一种奇怪的、不现实的做事方式。但是,它会/应该起作用吗

更新:即使在设置setBlockNetworkLoads(false)之后,它仍然不起作用

setBlockNetworkLoads(false) 我试着记录JS调用和错误,结果发现了这个错误

请求标头字段X-Requested-With不允许由 访问控制允许标头


知道如何解决这个问题吗?

我遇到了一个类似的问题,我在本地将一个“web应用程序”加载到
网络视图中,只是远程执行Ajax。我观察到一个类似的问题,Javascript警报等工作正常,但AJAX调用没有。结果是默认情况下,
WebView

请确保执行以下操作:

webView.getSettings().setBlockNetworkLoads(false)


那是为了我。为了澄清,我没有使用Javascriptinterface—只是像使用webView.loadDataWithBaseUrl()
一样加载web应用程序—传递给此方法的baseUrl参数是我执行所有AJAX调用的地方(因为此方法遵守相同的源策略)

似乎您正在尝试执行跨域AJAX请求

同一来源策略不允许跨域请求,因此请求将被阻止。如果您在webView中加载一个本地文件,然后将ajax请求从该文件发送到其他域,则会出现这种情况

如果是这种情况,并且是同源策略给您带来了麻烦,那么您可能需要研究跨源资源共享(CORS)或JSONP来解决这个问题

考虑到您得到的错误,您的问题似乎与此处讨论的问题类似:

您可能希望更改服务器设置以允许X-Requested-With标头


另外,似乎从API级别16开始,webSettings添加了一个方法setAllowFileAccessFromFileURLs()。对于webView,将此设置为true也可以解决此问题。

1。您的权限中是否有android.permission.INTERNET
?2.将链接粘贴到您请求的页面或.html文件的开头或
WebView
中加载的任何内容。3.您正在使用:可能是线程问题-UI线程(视图)和用于ajax请求的线程之间存在问题我有权限。为什么我需要在这里使用WebViewClient?@Uris不太明白你提到的问题。你能详细说明一下吗?UI是在UI线程上运行的。我假设你的回电是在另一个线程上。在回调线程中,您需要显式地使用runOnUiThread“返回”到UI。只是想确定问题确实出在ajax失败上,而不是它的响应的呈现上。文档说,如果你有INTERNET权限,默认值为false。我有上网许可。还是一样的结果。这里必须使用什么作为基本URL?我有INTERNET权限,如果IIRC,值仍然是
true
。为什么不在日志语句中打印
getBlockNetworkLoads()
的值并找出答案呢?关于baseUrl——它应该是提供AJAX请求的域或IP地址。AJAX请求中使用的相对路径将附加到baseUrl以形成完整的URL。您的AJAX调用将仅限于此域-对于我的请求,您将无法对其他域进行AJAX调用(这与同源策略保持一致),我执行post请求,并且只有一个URL。没有url路径。让我们以Github API为例:
POSThttps://api.github.com/user/repos
将创建新的回购协议。在JS中,您只需将
/user/repos
传递给XHR的
open
方法。这就是道路。
https://api.github.com
部分是基本URL。您将只允许在该域中调用API。例如,将不允许您调用StackOverflow API。此外,您是否尝试记录
getBlockNetworkLoads()
方法的值?我记得我为此得到了
true
。我必须显式地将其设置为
false
,才能使事情正常进行。CORS或JSONP是否也适用于POST请求?我想我在某个地方读到JSONP不适用于POST,这似乎是CORS的问题。目前,我还没有办法修复服务器端来检查这一点。但是,我已经调试了浏览器端的Javascript控制台,以及服务器日志。