【问题标题】:How to get access to XHR in $http with Angular?如何使用 Angular 在 $http 中访问 XHR?
【发布时间】:2013-05-22 01:42:25
【问题描述】:
目前我正在尝试使用 Angular 实现上传功能。起初我使用 XmlHttpRequest,但后来我将其更改为 $http。所以我发现我无法访问
XmlHttpRequest 使用 $http 创建进度条。下面是我的代码。关于上传图片时创建进度条的任何建议?谢谢。
$http({
method: 'POST',
url: upload_url,
data: fd,
headers: {'Content-Type': undefined},
transformRequest: angular.identity
})
【问题讨论】:
标签:
angularjs
xmlhttprequest
progress-bar
【解决方案1】:
这里获取xhr对象的方式:
http://boylesoftware.com/blog/angular-tip-using-the-xmlhttprequest-object/
复制/粘贴:
通常,AngularJS 应用程序使用 $http 服务来创建
调用后端服务。然而,有时我们希望拥有
访问底层 XMLHttpRequest 对象。我可以想出一个
用例很少,但最突出的一个可能是能够
跟踪长请求的进度,例如文件上传。要做到这一点,
我们需要在 XMLHttpRequest 对象上注册一个事件监听器
“进行中”的事件。令人惊讶的是,Angular 的 $http
服务不会以任何方式暴露底层 XMLHttpRequest
目的。所以,我们必须要有创意。这是一种方法……
$http 服务的配置对象允许我们将标头添加到 HTTP
通过其“headers”属性请求。这意味着在某些时候
$http 必须在它使用的 XMLHttpRequest 对象上设置这些标头。
这样做的方法是使用 XMLHttpRequest 的 setRequestHeader 方法。
所以想法是重写 setRequestHeader 方法
XMLHttpRequest 的原型并使用特殊的头部名称来介绍
一个钩子。让我们从它开始并创建一个简单的 Angular 模块
在其配置阶段执行方法替换:
angular.module("bsworksXHR", []).config([
function() {
XMLHttpRequest.prototype.setRequestHeader = (function(sup) {
return function(header, value) {
if ((header === "__XHR__") && angular.isFunction(value))
value(this);
else
sup.apply(this, arguments);
};
})(XMLHttpRequest.prototype.setRequestHeader);
}
]);
现在,当我们调用 $http 服务时,我们可以添加一个名为
“XHR” 具有将接收 XMLHttpRequest 的函数值
对象作为它的唯一参数。例如,在其他地方
应用:
$http({
…
headers: {
…
__XHR__: function() {
return function(xhr) {
xhr.upload.addEventListener("progress", function(event) {
console.log("uploaded " + ((event.loaded/event.total) * 100) + "%");
});
};
},
…
},
…
}).success(…);
希望 AngularJS 的未来版本将包含一些官方方式
访问低级 XMLHttpRequest 对象,即使是有限的,例如
能够注册事件侦听器或翻译
XMLHttpRequest 事件转化为 Angular 事件。在那之前,我正在使用
在我的应用中使用上述方法。
【解决方案2】:
这可以为您服务:
$http.post('http://url.com', {parameter1:'parameter', parameter2: 'secondparameter'}).success(function (result) {
console.log(result.data);
}).error(function(data, status, headers, config) {
console.log(status);
}));
【解决方案3】:
您可以使用 $http 配置的 eventHandlers 属性来注册一个 XMLHttpRequest 侦听器,这将为您提供进度:
var onProgress = function(event) {
if (event.total) {
var progress = event.loaded * 100 / event.total;
// do stuff
}
};
$http({
method: 'POST',
url: upload_url,
data: fd,
headers: {'Content-Type': undefined},
transformRequest: angular.identity,
uploadEventHandlers: { progress: onProgress }
});
我认为这应该涵盖您的用例。我认为您也可以在事件侦听器中使用this 来获取 XmlHttpRequest 实例。