4

This might seem to be a weird problem, but I am curious to know if it would work. I am working on a POC, and hence have to either prove or disprove that this works or not.

The UI in the Android app would be native (Java + XML layouts) + some other device features access like (Camera/File system etc).

There is a JS library that I have built, that has a few functions which do Ajax post and get requests.

In the app, I have an invisible Webview, where I load a blank HTML (referencing this JS library). And into that WebView, I have injected a JavascripInterface. So, essentially, the UI would be native, and you would never see the Webview. That's just a host which provides access to my JS library to the native code.

Now, on some action on my UI, I call the JS functions on the Webview, which in turn tries to make an ajax call (loadUrl calls ex. javascipt:functionName()). But, those calls fail, without any visible errors.

Note: This same HTML file works, if I load it up on my desktop browser. The AJAX calls succeed.

But, when I initiate Ajax calls through the JavascriptInterface(or webview.loadUrl() calls), they fail, with a reponse status 0.

Things apart from AJAX, like simple function calls, alerts, and callbacks through javascript interface work fine though.

Q: I know this is a weird and an unpractical way to do things. But, would it/should it work?

Update: Even after setting the

setBlockNetworkLoads(false)
, it still doesn't work.

I tried logging the JS calls and errors, and got this error.

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

Any idea how to solve this?

7
  • 1. Do you have android.permission.INTERNET in the permissions? 2. Paste a link to the page you're requesting or the beginning of the .html file or whatever gets loaded in the WebView. 3. Are you using : developer.android.com/reference/android/webkit/… Commented Jul 29, 2013 at 9:03
  • might be a threading issue - problems between the UI thread (of the view) and the one used for the ajax request Commented Jul 29, 2013 at 9:23
  • I have the permission. Why would I need to use WebViewClient here? Commented Jul 29, 2013 at 9:30
  • @uriz Didn't quite get the problem you have mentioned. Could you please elaborate on that? Commented Jul 29, 2013 at 9:31
  • The UI runs on the UI thread. And I'm assuming your callback is on another thread. from the callback thread you would need to explicitly use runOnUiThread to "get back" to the UI. Just wanted to make sure that the issue is indeed with the ajax failing, and not with the presentation of its response. Commented Jul 29, 2013 at 9:37

2 Answers 2

1

It seems that your are trying to do a cross domain ajax request.

Cross domain requests are not allowed by same origin policy and so the requests will be blocked. If you are loading a local file in webView and then sending ajax requests from it to other domains, this will be the case.

You if that is the case and it is the same origin policy causing you trouble then you might want to look at Cross-origin Resource Sharing (CORS) or JSONP to workaround it.

Given the error you get it seems that your problem is similar to one discussed here: Cross-Domain AJAX doesn't send X-Requested-With header

You might want to change server settings to allow X-Requested-With header.

Also it seems that from API level 16, webSettings added a method setAllowFileAccessFromFileURLs(). Setting this to true for the webView might solve the problem as well.

Sign up to request clarification or add additional context in comments.

2 Comments

Will CORS or JSONP work for POST requests as well? I think I read somewhere that JSONP doesn't work for POST
Seems like a CORS issue. Currently, I don't have a way to fix the server side to check this though. But, I have debugged the Javascript console on my browser side, and also the server logs.
0

I had a similar issue where I was loading a "web-app" locally into a WebView, just doing Ajax remotely. I observed a similar problem where Javascript alerts etc worked fine, but AJAX calls didn't. It turned out that by default the WebView blocks "network loads".

Make sure you do this:

webView.getSettings().setBlockNetworkLoads(false);

That did it for me. Just to clarify, I wasn't using a Javascriptinterface - just loading a web-app as-is using webView.loadDataWithBaseUrl() - the baseUrl parameter passed to this method was where I perform all my AJAX calls (since this method respects the same origin policy)

6 Comments

The docs say that the default value is false if you have INTERNET permission. I have INTERNET permission. Still the same result. What has to be used as the baseURL here?
I had INTERNET permission and if IIRC, the value was still true. Why don't you print the value of getBlockNetworkLoads() in a log statement and find out? Regarding baseUrl - that should be the domain or IP address from where your AJAX requests are served. The relative paths that you use in your AJAX requests are appended to the baseUrl to form the complete URL. Your AJAX calls will be restricted to this domain only - you won't be able to make AJAX calls to other domains (this is in keeping with the same origin policy)
For my requests, I do post request, and there is only one URL. There are no url paths.
Let's take Github API as an example: POST https://api.github.com/user/repos will create a new repo. In JS, you would just pass /user/repos to XHR's open method. That is the path. The https://api.github.com portion is the baseUrl. You will only be allowed to make calls to API's at that domain. You won't, for example, be allowed to make calls to StackOverflow API's.
Also, did you try logging the value of getBlockNetworkLoads() method? I remember getting true for that. I had to explicitly set it to false to get things working.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.