[ https://issues.apache.org/jira/browse/CB-4873?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Maris Seimanovs updated CB-4873: -------------------------------- Attachment: CordovaWP8_WP8.1_3.4.1.zip I attached a Visual Studio 2013 project generated with Cordova 3.4.0. CLI. I took the default.html file from the attached Corodva 3.6.0 project but I did not change the index.js file to keep things simple. This Cordova 3.4.0. project does not throw any exceptions (as 3.6.0 did) on WP8.1 emulator even without the XHRHelper fix, but the AJAX issue is clearly reproducable - the green box get filled with "REd" and no alert is shown because oneDone never passes the check for "true" value as only one of both AJAX requests return. I suspect that the exception thrown on WP8.1 in the 3.6.0 project is the result of some other changes in Cordova combined with XHRHelper issue and some other changes of WP8.1 WebBrowser control itself. Although XHRHelper fix applied to 3.6.0 prevents the exceptions and fixes also the AJAX issue, there might be something else broken for WP8.1, and who knows whether it's Cordova's or Microsoft's fault. I guess, we'll have to wait until WP8.1 is announced to be final RTM before trying to support it. Nevertheless, the XHRHelper fix seems still good solution because it safeguards us no matter if in final WP8.1 AJAX response and script processing is truly asynchronous or not. > XHRHelper is failing with simultaneous asynchronous requests > ------------------------------------------------------------ > > Key: CB-4873 > URL: https://issues.apache.org/jira/browse/CB-4873 > Project: Apache Cordova > Issue Type: Bug > Components: WP7, WP8 > Affects Versions: 3.0.0 > Environment: Any > Reporter: Jonathan Naguin > Assignee: Jesse MacFadyen > Priority: Critical > Labels: WP8, WP8.1, ajax, asynchronous, multiple, xhrhelper > Attachments: CordovaWP8_3.6.0-dev1.zip, CordovaWP8_WP8.1_3.4.1.zip > > > XHRHelper is failing in processing mutiple simultaneous asynchronous AJAX > requests. I am using the latest code from > https://github.com/apache/cordova-wp8/blob/master/wp8/template/cordovalib/XHRHelper.cs > The problem is related with {{_onXHRLocalCallback}} which is save into the > {{window}} object as a unique function. When, for example, two Ajax requests > are evaluated at same time, the last {{funk}} function overrides the first > {{_onXHRLocalCallback}} without receive the data from the C# code to that > particular request. > To demostrate this I put {{console.log("XHR: " + resolvedUrl);}} inside > {{__onXHRLocalCallback}} and > {{System.Diagnostics.Debug.WriteLine("HandleCommand: " + url);}} in > {{HandleCommand}} method (my code uses *Require JS* to load this resources). > The output is this: > {code} > HandleCommand: x-wmapp0:www/src/modules/home/HomeView.html > HandleCommand: x-wmapp0:www/src/modules/orders/OrdersView.html > XHR: x-wmapp0:www/src/modules/orders/OrdersView.html > XHR: x-wmapp0:www/src/modules/orders/OrdersView.html > XHR: HandleCommand: x-wmapp0:www/src/modules/order/OrderDetailView.html > XHR: x-wmapp0:www/src/modules/order/OrderDetailView.html > {code} > As you can see, one request is missing: "HomeView.html". > h6. NOTES > - If I set {{false}} the {{this.isAsync}} variable it works (this way it is > executed without using setTimeout). > - If I put a console.log before launch {{funk}} it works. > - It works on the simulator, but it fails on a real device. > h6. Possible solution > In conclusion, I assumed that it's a timing problem. To resolve it I decided > to save a onXHRLocalCallback function per each request: > {code} > var funk = function () { > if (! window.__onXHRLocalCallback){ > window.__onXHRLocalCallback = {}; //Object to store the functions > } > > window.__onXHRLocalCallback[resolvedUrl] = function (responseCode, > responseText) { > alias.status = responseCode; > if (responseCode == '200') { > alias.responseText = responseText; > } > else { > alias.onerror && alias.onerror(responseCode); > } > alias.changeReadyState(XHRShim.DONE); > delete window.__onXHRLocalCallback[resolvedUrl]; //Delete the function > } > alias.changeReadyState(XHRShim.LOADING); > window.external.Notify('XHRLOCAL/' + resolvedUrl); > } > {code} > So I had to change in {{HandleCommand}} method the way of invoking this > callback. I decided to create a helper function to be called in each case: > {code} > /// <summary> > /// Invoke a XHR callback > /// </summary> > /// <param name="url">The URL of the request</param> > /// <param name="code">The response code</param> > /// <param name="text">The response text</param> > private void InvokeCallback(string url, int code, string text) > { > string args = string.Format("('{0}', {1}, {2});", code, > WPCordovaClassLib.Cordova.JSON.JsonHelper.Serialize(text), > WPCordovaClassLib.Cordova.JSON.JsonHelper.Serialize(url)); > string callback = @"(function(code, text, url){ > try { > window.__onXHRLocalCallback[ url ].call(null, code, text); > } > catch(e) { > console.log('Error calling method from XHRHelper :: ' + e); > } > })" + args; > Browser.InvokeScript("eval", new string[] { callback }); > } > {code} > To be called as {{InvokeCallback(url, 200, text);}} or {{InvokeCallback(url, > 404, null);}} > Thanks. -- This message was sent by Atlassian JIRA (v6.2#6252)