服务器返回重定向(302)后,iOS设备上的AJAX或XHR请求失败,代码为0

AJAX or XHR request on iOS device failed with code 0 after server returns redirect (302)

本文关键字:AJAX XHR 请求 代码 失败 重定向 返回 iOS 服务器      更新时间:2023-09-26

我正在开发一个移动应用程序,它是用Cordova(PhoneGap)开发的。我的基本代码是用JavaScript编写的,它被编译成原生Android和iOS代码。在我的一个加载XML的请求中,我向UrlA发送了一个请求,服务器将该请求重定向(状态302)到UrlB。然后从UrlB返回一个带有XML的响应。

所有这些过程在安卓设备上(以及桌面上)都很有效。

但在iOS设备上,由于某种原因,对UrlA的请求失败,代码为0。

我试图将我的请求表单jQuery的Ajax更改为带有XHR对象的纯JS解决方案。但结果是一样的。

原始Ajax请求(仅适用于Android)

$.ajax(
{
   type: "GET",
   url: xmlUrl,
   dataType: "xml",
   crossDomain: true,
   async: true,
   timeout: 7000, // 7sec before timeout failure
   beforeSend: function(xhr)
   {
      //xhr.setRequestHeader("Access-Control-Allow-Origin", "*");                                  
      xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
      xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.8,he;q=0.6");
      xhr.setRequestHeader("Accept-Encoding", "gzip, deflate, sdch");
   },
   // Request succeed
   success: successCallback,                                 
   // Request failed
   error: errorCallback
}

我的第二次尝试,使用XHR请求(仅适用于Android)

var XHR = new XMLHttpRequest();
if (XHR)
{
   var method = 'GET';
   var isAsync = true;
   XHR.onreadystatechange = function()
   {
      switch (XHR.readyState)
      {
         case 0:
            console.log("# XHR: State 0 - Request isn't initialized");
            break;
         case 1:
            console.log("# XHR: State 1 - Request was set up");
            break;
         case 2:
            console.log("# XHR: State 2 - Request was sent");
            break;
         case 3:
            console.log("# XHR: State 3 - Request in progress");
            break;
         case 4:
            console.log("# XHR: State 4 - Request is completed");
            if (XHR.status == 200) // OK
            {
               console.log("# XHR: Request Success!");
               console.log(XHR);
               var responseText = XHR.responseText;
               var responseXml = XHR.responseXML;
               successCallback(responseXml)
            }
            else // request failed
            {
               console.warn("# XHR: Request Failed!");
               console.log(XHR);
               failerCallback("# XHR: Request failed! [Status: " + XHR.status + "]");
            }
            break;
            default:
               console.log("# XHR: Unknown ReadyState [" + XHR.readyState + "]");
               break;
      }
   };
   XHR.open(method, xmlUrl, isAsync);
   XHR.send(); // Start request
}
else
{
   failerCallback("XHR isn't defined");
}

我还注意到,在Android设备上,当使用XHR对象运行代码时,我们会得到所有readyState(1到4,一个在外)但在iOS设备上,我们只能获得readyState 1和readyState4,但状态代码为0。

替换

if (XHR.status == 200) // OK

带有

if ((XHR.status >= 200 && XHR.status < 300) ||
   (XHR.status === 0 && !!XHR.responseXML))