如何使用Angular访问$ http中的XHR?

时间:2021-05-02 16:00:49

Currently I am try to implement the upload function with Angular. At first I used XmlHttpRequest but later I changed it to $http. So I found that I could't get access to XmlHttpRequest to create a progress bar with $http. Below is my code. Any suggestions about create a progress bar when uploading images? Thanks.

目前我尝试使用Angular实现上传功能。起初我使用XmlHttpRequest,但后来我将其更改为$ http。所以我发现我无法访问XmlHttpRequest来创建一个带有$ http的进度条。以下是我的代码。有关上传图片时创建进度条的任何建议吗?谢谢。

    $http({
          method: 'POST',
          url: upload_url,
          data: fd, 
          headers: {'Content-Type': undefined}, 
          transformRequest: angular.identity
          })

3 个解决方案

#1


2  

Here the way of getting xhr object:

这里获取xhr对象的方式:

http://boylesoftware.com/blog/angular-tip-using-the-xmlhttprequest-object/

http://boylesoftware.com/blog/angular-tip-using-the-xmlhttprequest-object/

Copy/Paste:

Normally, an AngularJS application uses the $http service to make calls to back-end services. Sometimes, however, we would like to have access to the underlying XMLHttpRequest object. I can come up with a few use-cases, but the most prominent one is probably being able to track progress of a long request, such as a file upload. To do that, we need to register an event listener on the XMLHttpRequest object for the event that is “in progress.” Surprisingly enough, Angular’s $http service does not in any way expose the underlying XMLHttpRequest object. So, we have to get creative. Here is one way to do it…

通常,AngularJS应用程序使用$ http服务来调用后端服务。但是,有时我们希望能够访问底层的XMLHttpRequest对象。我可以提出一些用例,但最突出的用例可能是跟踪长请求的进度,例如文件上传。为此,我们需要在XMLHttpRequest对象上为“正在进行中”的事件注册一个事件监听器。令人惊讶的是,Angular的$ http服务不会以任何方式公开底层的XMLHttpRequest对象。所以,我们必须发挥创意。这是一种方法......

The $http service’s config object allows us to add headers to the HTTP request via its “headers” property. That means that at some point $http has to set those headers on the XMLHttpRequest object it uses. The way to do that is to use XMLHttpRequest’s setRequestHeader method. So the idea is to override the setRequestHeader method on the XMLHttpRequest’s prototype and use a special header name to introduce a hook. Let’s begin with that and create a simple Angular module that performs the method substitution in its configuration phase:

$ http服务的配置对象允许我们通过其“headers”属性向HTTP请求添加标头。这意味着在某些时候,$ http必须在它使用的XMLHttpRequest对象上设置这些头。这样做的方法是使用XMLHttpRequest的setRequestHeader方法。因此,我们的想法是覆盖XMLHttpRequest原型上的setRequestHeader方法,并使用特殊的头名称来引入钩子。让我们从这开始,创建一个简单的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);
    }
]);

Now, when we make an $http service call, we can add a header called “XHR” with a function value that will receive the XMLHttpRequest object as its only argument. For example, somewhere else in the application:

现在,当我们进行$ 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(…);

Hopefully, future versions of AngularJS will include some official way to access the low-level XMLHttpRequest object, even if limited, such as being able to register event listeners or translating the XMLHttpRequest events into Angular events. Until then, I am using the approach above in my apps.

希望AngularJS的未来版本将包括访问低级XMLHttpRequest对象的一些官方方法,即使有限,例如能够注册事件侦听器或将XMLHttpRequest事件转换为Angular事件。在那之前,我在我的应用程序中使用上述方法。

#2


0  

This can serve you:

这可以为您服务:

            $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


0  

You can use $http config's eventHandlers property to register an XMLHttpRequest listener, which will give you the progress:

您可以使用$ http config的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 }
      });

I think that should cover your use case. I think you can also use this inside of an event listener to get the XmlHttpRequest instance.

我认为这应该涵盖你的用例。我想你也可以在事件监听器中使用它来获取XmlHttpRequest实例。

#1


2  

Here the way of getting xhr object:

这里获取xhr对象的方式:

http://boylesoftware.com/blog/angular-tip-using-the-xmlhttprequest-object/

http://boylesoftware.com/blog/angular-tip-using-the-xmlhttprequest-object/

Copy/Paste:

Normally, an AngularJS application uses the $http service to make calls to back-end services. Sometimes, however, we would like to have access to the underlying XMLHttpRequest object. I can come up with a few use-cases, but the most prominent one is probably being able to track progress of a long request, such as a file upload. To do that, we need to register an event listener on the XMLHttpRequest object for the event that is “in progress.” Surprisingly enough, Angular’s $http service does not in any way expose the underlying XMLHttpRequest object. So, we have to get creative. Here is one way to do it…

通常,AngularJS应用程序使用$ http服务来调用后端服务。但是,有时我们希望能够访问底层的XMLHttpRequest对象。我可以提出一些用例,但最突出的用例可能是跟踪长请求的进度,例如文件上传。为此,我们需要在XMLHttpRequest对象上为“正在进行中”的事件注册一个事件监听器。令人惊讶的是,Angular的$ http服务不会以任何方式公开底层的XMLHttpRequest对象。所以,我们必须发挥创意。这是一种方法......

The $http service’s config object allows us to add headers to the HTTP request via its “headers” property. That means that at some point $http has to set those headers on the XMLHttpRequest object it uses. The way to do that is to use XMLHttpRequest’s setRequestHeader method. So the idea is to override the setRequestHeader method on the XMLHttpRequest’s prototype and use a special header name to introduce a hook. Let’s begin with that and create a simple Angular module that performs the method substitution in its configuration phase:

$ http服务的配置对象允许我们通过其“headers”属性向HTTP请求添加标头。这意味着在某些时候,$ http必须在它使用的XMLHttpRequest对象上设置这些头。这样做的方法是使用XMLHttpRequest的setRequestHeader方法。因此,我们的想法是覆盖XMLHttpRequest原型上的setRequestHeader方法,并使用特殊的头名称来引入钩子。让我们从这开始,创建一个简单的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);
    }
]);

Now, when we make an $http service call, we can add a header called “XHR” with a function value that will receive the XMLHttpRequest object as its only argument. For example, somewhere else in the application:

现在,当我们进行$ 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(…);

Hopefully, future versions of AngularJS will include some official way to access the low-level XMLHttpRequest object, even if limited, such as being able to register event listeners or translating the XMLHttpRequest events into Angular events. Until then, I am using the approach above in my apps.

希望AngularJS的未来版本将包括访问低级XMLHttpRequest对象的一些官方方法,即使有限,例如能够注册事件侦听器或将XMLHttpRequest事件转换为Angular事件。在那之前,我在我的应用程序中使用上述方法。

#2


0  

This can serve you:

这可以为您服务:

            $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


0  

You can use $http config's eventHandlers property to register an XMLHttpRequest listener, which will give you the progress:

您可以使用$ http config的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 }
      });

I think that should cover your use case. I think you can also use this inside of an event listener to get the XmlHttpRequest instance.

我认为这应该涵盖你的用例。我想你也可以在事件监听器中使用它来获取XmlHttpRequest实例。