Adam M. Smith created CB-9345:
---------------------------------
Summary: wp8 ajax does not work
Key: CB-9345
URL: https://issues.apache.org/jira/browse/CB-9345
Project: Apache Cordova
Issue Type: Bug
Components: WP8
Affects Versions: 3.8.0
Environment: -Windows 8.1, Visual Studio 2013 Pro, Cordova 5.1.1, wp8
3.8.1
-NOKIA Lumia 1520, Windows Phone 8.0
Reporter: Adam M. Smith
Assignee: Jesse MacFadyen
Priority: Blocker
wp8 platform builds do not successfully complete ajax requests.
Note: The 'Affects Version' picker when creating this issue report did not
allow me to use the actual version of 3.8.1. I picked the 'unreleased' version
of 3.8.0, however, 3.8.1 is the version that is given by default when adding
the platform and is listed as a release in github.
*Client Setup*
1. Add wp8 platform: {{cordova platform add wp8}}
2. Add jquery as a dependency in {{index.html}}. I used a local copy and did
not try cdn.
3. Change Content-Security-Policy in {{index.html}} to have {{'default-src' *}}
4. Change {{index.js}} to the following in order to add tests
{code:javascript}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
console.log('Running connection test');
testConnections();
}
};
// You will need to change this to match your machine ip
var url = "http://test:1337/test/test";
function testConnections() {
console.log("Sending requests...");
try {
jqueryGet();
jqueryPost();
post();
get();
} catch (e) {
console.error(e);
console.log(e);
}
}
function jqueryGet() {
$.ajax(url, {
type: 'GET',
dataType: 'json',
contentType: 'application/json;charset=utf-8',
processData: false,
data: JSON.stringify({
userName: 'asmith'
}),
complete: function (jqXHR, textStatus) {
console.log("JQUERY GET: ");
console.log(JSON.stringify(jqXHR, null, 2));
}
});
}
function jqueryPost() {
$.ajax(url, {
type: 'POST',
dataType: 'json',
contentType: 'application/json;charset=utf-8',
processData: false,
data: JSON.stringify({
userName: 'asmith'
}),
complete: function (jqXHR, textStatus) {
console.log("JQUERY POST");
console.log(JSON.stringify(jqXHR, null, 2));
}
});
}
function post() {
var xmlHttp = new XMLHttpRequest();
var parameters = '{"userName" : "asmith"}';
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-type", "application/json;charset=utf-8");
xmlHttp.onreadystatechange = function() {
console.log("POST ready state: " + xmlHttp.readyState);
console.log(JSON.stringify(xmlHttp, null, 2));
};
xmlHttp.send(parameters);
}
function get() {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
// Success!
console.log('GET: ' + this.response);
} else {
console.log('GET: error in onload');
console.log(JSON.stringify(this, null, 2));
}
};
request.onerror = function() {
console.log('GET: error in onerror');
console.log(JSON.stringify(this, null, 2));
};
request.send('{"userName" : "asmith"}');
}
app.initialize();
{code}
{{config.xml}} is unchanged, but does include white list plugin default setting
{{<access origin="*" />}}.
*Server Setup*
I created a simple sails.js server for the test, but am using a client's IIS
server in production. Use any server for reproducing.
1. Install node.js
2. Install sails: {{npm install -g sails}}
3. Create sails app: {{sails new testAjaxServer}}
4. Create controller file for testing {{<root>/api/TestController.js}} and
populate it with
{code:javascript}
module.exports = {
test : function (req, res) {
sails.log("Got a request");
res.send('{"result":"hooray!"}');
}
};
{code}
5. Run the server from the root directory of the sails app: {{sails lift}}
6. Test server by visiting {{localhost:1337/test/test}}. You should see the
json result that is specified in the test controller.
*Expected*
Loading this {{index.html}} in chrome and running {{testConnections()}}
produces the correct output as shown below.
{code}
Sending requests...
undefined
index.js:136 GET: {"result":"hooray!"}
index.js:88 JQUERY GET:
index.js:89 {
"readyState": 4,
"responseText": "{\"result\":\"hooray!\"}",
"responseJSON": {
"result": "hooray!"
},
"status": 200,
"statusText": "OK"
}
index.js:119 POST ready state: 2
index.js:120 {
"response": "",
"responseText": ""
}
index.js:119 POST ready state: 3
index.js:120 {
"response": "{\"result\":\"hooray!\"",
"responseText": "{\"result\":\"hooray!\""
}
index.js:104 JQUERY POST
index.js:105 {
"readyState": 4,
"responseText": "{\"result\":\"hooray!\"}",
"responseJSON": {
"result": "hooray!"
},
"status": 200,
"statusText": "OK"
}
index.js:119 POST ready state: 3
index.js:120 {
"response": "{\"result\":\"hooray!\"}",
"responseText": "{\"result\":\"hooray!\"}"
}
index.js:119 POST ready state: 4
index.js:120 {
"response": "{\"result\":\"hooray!\"}",
"responseText": "{\"result\":\"hooray!\"}"
}
{code}
*Actual*
Running the same code deployed to a wp8 device produces the following.
{code}
Received Event: deviceready
Running connection test
Sending requests...
POST ready state: 1
{
"wrappedXHR": {},
"readyState": 1
}
JQUERY POST
{
"readyState": 4,
"responseText": "",
"status": 200,
"statusText": "parsererror"
}
POST ready state: 4
JQUERY GET:
{
"readyState": 4,
"responseText": "",
"status": 200,
"statusText": "parsererror"
}
{
"wrappedXHR": {},
"readyState": 4
}
GET: error in onload
{
"wrappedXHR": {},
"readyState": 4
}
{code}
The jquery functions have a 200 response, but fail due to a 'parserror'. There
is no response text. The vanilla js tests fail for an undisclosed reason. The
server logs indicate that there was never any established connection. I am
able to hit my server from the phone's browser and get the json response.
Interestingly, when running the test in IE11 I get the following error:
{{SCRIPT7002: XMLHttpRequest: Network Error 0x2efd, Could not complete the
operation due to error 00002efd.}}. There could be a similar error occurring
in the device, but I am not sure how to capture it. In any case, I believe
that I have followed all of the documentation for settings up the test project
for using ajax calls, so if there is other configuration required then at least
there needs to be a doc update.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]