XMLHttpRequest - empty responseText but status 200 and readyState 4
I've been trying to do a cross domain request with plain JS. It does work in Firefox and Chromium but not in Android Emulator.
The onload method returns success (status 200 and readyState 4) but the responseText is empty.
window.addEventListener('load', function () {
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open('GET', 'http://10.2.1.22/'); // My website running in local apache right now. It'll be in a webhosting.
xmlHttpRequest.addEventListener('load', function () {
document.body.appendChild(document.createTextNode(this.status + " - " + this.readyState)); // output: "200 - 4"
document.body.appendChild(document.createTextNode(this.responseText)); // in browser output is a regular string ... in android emulator it's an empty string.
});
xmlHttpRequest.addEventListener('error', function (event) {
document.body.appendChild(document.createTextNode("Error!")); // it's never called.
});
xmlHttpRequest.send();
});
My website sends these headers:
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json; charset=UTF-8');
Cordova version:
$ cordova --version
3.4.0-0.1.3
EDIT
app_root/config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.xmlhttprequest" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>XMLHttpRequest</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="dev#cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<access origin="*" />
</widget>
Did you add your site to the whitelist in config.xml? By default, all documents that are whitelisted will return an empty document if you didn't explicitly whitelist it. This is by design. You should probably read about the whitelist:
http://docs.phonegap.com/en/3.4.0/guide_appdev_whitelist_index.md.html#Whitelist%20Guide
Related
I have a phonegap application that works fine (ajax http requests are executed, etc) when opened/loaded through the official phonegap app.
But when I upload and build the application and download the apk from the build.phonegap website, none of the external http requests work.
I also noticed that since I am on android that no permissions were ever requested for the application on install or on service request(6.0+) and when looking at the application in the app manager it is listed as using no permissions. So I am assuming that without the internet permission my app is not being allowed to connect for http requests.
So my question is how do I get it to request the permissions for internet, etc that I need? I thought phonegap was supposed to default request things like internet and a few others but it seems like they are not being requested at all.
I will also note however that in the app the only platform listed in the platforms folder is browser so I do not have a platforms->android->config.xml to do any potential edits in as I have seen suggested in a couple places on this site but my project root config.xml looks like this with my potentially sensitive info replaced with *******'s.
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.******.mainapp" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
<name>********</name>
<description>
**********
</description>
<author email="*******" href="********">
***********
</author>
<content src="index.html" />
<access origin="http://*******.com/*" />
<access origin="http://admin.*******.com/*" />
<access origin="*" />
<preference name="Orientation" value="portrait" />
</widget>
EDIT: Any potential help, suggestions, or advice would be helpful and appreciated as I have been trying to solve this problem all day to no avail
EDIT2: Example request in the app
var http = new XMLHttpRequest();
var url = "http://www.********.com/functions/*******.php";
http.open("GET", url, true);
http.send();
http.onreadystatechange = function() {
if (http.readyState == 4) {
if (http.responseText.indexOf("success") >= 0) {
var data = http.responseText.split(" - ")[1];
populate(data);
} else {
alert(http.responseText);
}
loadingScreen.style.display = "none";
}
};
Answer originally from Kerri Shotts solved my problem,
config.xml needed to include the line
<plugin name="cordova-plugin-whitelist" source="npm" spec="~1.2.1" />
Once this is added everything works as expected
I have just upgraded from Cordova v3.4 to latest 6.1.1. My whole android app is working just fine apart from ALL jquery Ajax calls here is a sample one:
var baseUrl = 'http://gazetkisklepowe.pl';
$.ajax({
url: baseUrl+"/api/get/favourites",
data: {
user_uuid: device.uuid
}
}).done(function(data) {
}).fail(function() {
alert('Error connecting. (100) '+baseUrl+"/api/get/favourites");
return null;
});
I have read this article: PhoneGap / Android WebView throws "Unknown chromium error: 0" but I haven't found a solution for me.
The message in the LogCat just displays: "unknown chromium error: 0"
My config.xml contains:
<access origin="*" />
<access origin="mailto:*" launch-external="yes"/>
SN: I would like just to inform that previously on Cordova v3.4 all Ajax requests worked just fine and there have not been any changes in the code since then.
UPDATE 10am 5/04/2016
I have added whitelist plugin and <allow-navigation href="data:*" /> to the config.xml, now I get:
object has no method 'error' at file ///android_asset/www/plugins/cordova-plugin-whitelist/whitelist.js:24
Line 24 in that js file is: console.error(msg); so from some reason console is not fully defined.
UPDATE 2pm 05/04/2016
I have created new cordova app in separate folder and copied my files over, that done the trick and have fixed everything.
I am trying to connect to server for fetching data using ajax call inside phonegap app.
But I am getting status 404 for every request I tried google.com, 10.0.2.2 (localhost on android).
Here are steps I followed for creating application
I created template application using phonegap command line as phonegap create my-app
Running application using phonegap run android ( This shows "device is ready" screen on emulator )
Added following code for making an Ajax call to index.js - receivedEvent function
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
console.log('rdy state - '+ xmlhttp.readyState);
console.log('status - '+ xmlhttp.status);
console.log('text status - '+ xmlhttp.statusText);
console.log('Response Text - '+ xmlhttp.responseText);
}
xmlhttp.open("GET","http://10.0.2.2/", true);
xmlhttp.send();
I can access http://10.0.2.2 from emulator browser.
Here is Enviornment I am using
Phonegap version - 3.4.0-0.19.8
Android version - 4.4.2
-- Vishal
Did you put an access token in your config.xml? Try to put
<access origin="*"/>
into your config.xml.
* gives access to all domain.
Look up http://docs.phonegap.com/en/3.4.0/guide_appdev_whitelist_index.md.html#Whitelist%20Guide for further information.
Despite you have:
<pre> <access origin="*"/> </pre> in config.xml
You need to add the whitelist to your phonegap(cordova) project:
phonegap plugin add cordova-plugin-whitelist
After this your app will no longer give 404.
hoping anyone can figure this out, have been battling with this issue the whole day.
I'm trying to browse through folders on the file system to select a file, but I cannot seem to connect to the file system.
When ever I call "window.requestFileSystem", the error callback returns a "Class not found" error. Going into Cordova's "requestFileSystem" function, I notice the "Class not found" is returned during the exec() call (where I can't trace it).
Did anyone get past this problem, or know how to fix it?
I am aware it's listed on several forums, but the fixes suggested there don't work for me.
As far as I can see, all the plugins are there. Installed using Cordova CLI, they appear in the plugin folder. I do wonder if the file plugin is actually loaded, not sure how I can verify that..
org.apache.cordova.console
org.apache.
cordova.device org.apache.cordova.file
org.apache.cordova.file-transfer
www/index.html
<body onload="onLoad();">
<script type="text/javascript">
// Init when we're good and ready.
function onLoad(){document.addEventListener('deviceready', init, true);}
// Init :)
function init(){
// window.requestFileSystem is recognized, so far so good.
window.requestFileSystem(1, 0, function(fileSystem){
alert('success');
}, function(e){
// 'e' is an object, {code: 'Class not found'}
alert('Error accessing local file system');
});
}
</script>
<div class="app">
<h1>Apache Cordova</h1>
...
</div>
<script type="text/javascript" src="cordova.js"></script>
</body>
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.fwd.cwptakeonsheetsv1" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>CWPTakeOnSheetsV1</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="dev#cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<access origin="*" />
<feature name="App">
<param name="android-package" value="org.apache.cordova.App" />
</feature>
<feature name="Device">
<param name="android-package" value="org.apache.cordova.device.Device" />
</feature>
<feature name="File">
<param name="android-package" value="org.apache.cordova.file" />
<param name="android-package" value="org.apache.cordova.file.FileUtils" />
<param name="onload" value="true" />
<param name="android-package" value="org.apache.cordova.FileUtils" />
</feature>
<feature name="FileTransfer">
<param name="android-package" value="org.apache.cordova.filetransfer.FileTransfer" />
</feature>
</widget>
Cordova's requestFileSystem.js
/**
* Request a file system in which to store application data.
* #param type local file system type
* #param size indicates how much storage space, in bytes, the application expects to need
* #param successCallback invoked with a FileSystem object
* #param errorCallback invoked if error occurs retrieving file system
*/
var requestFileSystem = function(type, size, successCallback, errorCallback) {
argscheck.checkArgs('nnFF', 'requestFileSystem', arguments);
var fail = function(code) {
errorCallback && errorCallback(new FileError(code));
};
if (type < 0) {
fail(FileError.SYNTAX_ERR);
} else {
// if successful, return a FileSystem object
var success = function(file_system) {
if (file_system) {
if (successCallback) {
// grab the name and root from the file system object
var result = new FileSystem(file_system.name, file_system.root);
successCallback(result);
}
}
else {
// no FileSystem object returned
fail(FileError.NOT_FOUND_ERR);
}
};
// The error happens in exec()
exec(success, fail, "File", "requestFileSystem", [type, size]);
}
};
I think I found the problem (at least in my case). I'd struggled with this one popping up over and over again:
Simply open up plugins/android.json and move any entries under the 'config.xml' heading to the 'res/xml/config.xml' heading.
I think this is an issue with certain plugins (in my case, Immersify) not having switched to the new config.xml location. After I fixed this, all of the 'missing' plugins magically appeared in my platforms/android/res/xml/config.xml file, and the 'class not found' errors disappeared.
Have you checked the android.json that is generated in the plugins folder?
I had a similar problem because some 'not yet updated to 3.4' plugins like sqlite generated wrong directions in this file (which is used at build time). That lead into removing some other plugins from my actual config.xml
I eventually solved my problem. Here are the steps I did to get it working:
Moved all the JavaScript to the head-section of my index.html (including references to .js files).
Took all the feature-tags out of config.xml. My /platforms/android/AndroidManifest.xml still contains:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Took all alerts() and custom debugging functions out of my code. I don't know if the delay caused issues or what, but it seems to have an effect.
I also noticed that if window.requestFileSystem is undefined, it is likely due to a JavaScript error which causes it not to load.
There's a good example of this here - Thanks Ram for publishing this.
Thanks #QuickFix for your reply!
Using PhoneGap 2.5.0 + jQuery 1.9.1 + jQueryMobile 1.3.0, I'm trying to download a remote JSON file:
$(document).ready(function() {
$.getJSON("http://foo.mydomain.com/json.php?callback=?",function(data) {
alert("It works");
})
});
I modified 'res/xml/config.xml' to allow remote accesses to my server:
<cordova>
<access origin="http://127.0.0.1*"/>
<access origin="http://foo.mydomain.com*" />
<content src="index.html" />
But it does not work. What am I doing wrong? Thank you very much in advance.
Probably it's a problem related with Access-Control-Allow-Origin Issue.
To solve this, you should use JSON-P in the ajax request.
Try something like this:
$.ajax({
type : "GET",
dataType : "jsonp",
url : 'your-external-url',
data : {},
success: function(obj){
}
});