5

This issue has been reproduced on PlayStation 3, 4, Xbox360, Xbox One. This issue is present with all versions of AjaxPro.

When making an Ajax request (using AjaxPro) the server returns the correct content. However, the object returned in the call back function is

{
   "error": 
    {
     "Message":"","Type":"ConnectFailure","Status":200},"value":null,
     "request":
     {
       "method":"MethodName",
       "args":
       {
          "Argument1":"1111","Argument2":"2222"
       }
     },
    "context":null,"duration":18
   }
}
Roman Mik
  • 3,179
  • 3
  • 27
  • 49

3 Answers3

10

In my case, I am having this same error when using AjaxPro with https, TLS 1.2, ECDHE_RSA with P-256 key exchange, and AES_256_GCM cipher (IE11+, Chrome51+, Firefox49+. Check yours here). It runs ok with obsolete AES_256_CBC with HMAC-SHA1 cipher.

The problem is that XMLHttpRequest.statusText property is empty after server response (I do not really know why) and AjaxPro.Request.prototype.doStateChange method (ajaxpro/core.ashx file) expected "OK" to take response as valid:

var res = this.getEmptyRes();
if(this.xmlHttp.status == 200 && this.xmlHttp.statusText == "OK") {
    res = this.createResponse(res);
} else {
    res = this.createResponse(res, true);
    res.error = {Message:this.xmlHttp.statusText,Type:"ConnectFailure",Status:this.xmlHttp.status};
}

I finally decided to override AjaxPro.Request.prototype.doStateChange method and allow an empty value in this.xmlHttp.statusText.

I added this script to my affected pages:

$(function() {
    if (typeof AjaxPro != 'undefined' && AjaxPro && AjaxPro.Request && AjaxPro.Request.prototype) {
        AjaxPro.Request.prototype.doStateChange = function () {
            this.onStateChanged(this.xmlHttp.readyState, this);
            if (this.xmlHttp.readyState != 4 || !this.isRunning) {
                return;
            }
            this.duration = new Date().getTime() - this.__start;
            if (this.timeoutTimer != null) {
                clearTimeout(this.timeoutTimer);
            }
            var res = this.getEmptyRes();
            if (this.xmlHttp.status == 200 && (this.xmlHttp.statusText == "OK" || !this.xmlHttp.statusText)) {
                res = this.createResponse(res);
            } else {
                res = this.createResponse(res, true);
                res.error = { Message: this.xmlHttp.statusText, Type: "ConnectFailure", Status: this.xmlHttp.status };
            }
            this.endRequest(res);
        };
    }
});
Rafael Neto
  • 1,036
  • 10
  • 16
5

Building on all the answers before this, and for reference for anyone else looking for this - in our situation, we tracked this down to the HTTP2 protocol (note - we were testing over HTTPS; I'm not sure there is a problem over HTTP...).
- When we disabled HTTP2 in the browser (or for IIS on the server) then the AjaxPro calls worked normally.
- When HTTP2 was being used, though, the response was a plain "200" instead of "200 OK", and AjaxPro interpreted that as a failure

z9_x
  • 101
  • 2
  • 6
2

The hint to this problem is in

"Message":""

AjaxPro's core.ashx file is generated using core.js

In the core.js, the following code is responsible for generating the response object when the server's response is received.

   if (this.xmlHttp.status == 200 && this.xmlHttp.statusText == "OK") {
        res = this.createResponse(res);
    } else {
        res = this.createResponse(res, true);
        res.error = { Message: this.xmlHttp.statusText, Type: "ConnectFailure", Status: this.xmlHttp.status };
    }

For some reason, the browsers on the identified platforms do not return xmlHttp.statusText as "OK". Instead it is empty. This causes AjaxPro to fall through into "ConnectionFailure" clause.

Roman Mik
  • 3,179
  • 3
  • 27
  • 49