2013-05-13 53 views
5

我需要访问原始XMLHttpRequest对象以在支持它的浏览器上添加文件上载进度回调。这是可能的,还是我必须自己构建原始请求?如果是这样,我该如何将原始XMLHttpRequest包装在承诺对象中?

回答

4

我模拟$http调用构造定制XMLHttpRequest像这样:

uploadFile(file, progressHandler) { 
    var xhr = new XMLHttpRequest(), 
     deferred = $q.defer(); 

    xhr.open("POST", "your/path", true); // method, url, async 
    xhr.setRequestHeader("Content-Type", file.type || "application/octet-stream"); 
    xhr.onreadystatechange = function (e) { 
    if (xhr.readyState == 4) { 
     $rootScope.$apply(function() { 
     // Construct a response object similar to a regular $http call 
     // 
     // data – {string|Object} – The response body transformed with the transform functions. 
     // status – {number} – HTTP status code of the response. 
     // headers – {function([headerName])} – Header getter function. 
     // config – {Object} – The configuration object that was used to generate the request. 
     var r = { 
      data: xhr.response, 
      status: xhr.status, 
      headers: xhr.getResponseHeader, 
      config: {} 
     }; 
     if (r.status == 200) { 
      deferred.resolve(r); 
     } else { 
      deferred.reject(r); 
     } 
     }); 
    } 
    }; 
    if (progressHandler && xhr.upload) { 
    xhr.upload.addEventListener('progress', function(e) { 
     progressHandler((e.loaded/e.total), e); 
    }, false); 
    } 
    // This is only available in XHR2, provide multipart fallback 
    // if necessary 
    xhr.send(file); 

    return deferred.promise; 
} 
+0

'getResponseHeader'不完全模仿正常响应提供'headers'功能。你也可能想把'xhr.response'改成'JSON.parse(xhr.response)',并且将'statusText'加入hash。 – 2015-07-14 08:58:12