Angularjs A workaround for $http asynchronous background failed to get request parameters _angularjs

Source: Internet
Author: User
Tags http request serialization

The example in this article describes a workaround for the angularjs occurrence of a $http asynchronous background failure to obtain request parameter problems. Share to everyone for your reference, specific as follows:

Angular uses a different form of request headers and data serialization when submitting data asynchronously, resulting in some background programs not parsing data properly.

Principle Analysis (on-line analysis):

For AJAX applications (using xmlhttprequests), the traditional way to initiate a request to a server is to get a reference to a XMLHttpRequest object, initiate a request, read a response, check the status code, and finally handle the service-side response. The entire process example is as follows:

var xmlhttp = new XMLHttpRequest ();
Xmlhttp.onreadystatechange = function () {
  if (xmlhttp.readystate = = 4 && xmlhttp.status =) {
    var resp Onse = Xmlhttp.responsetext;
  } else if (xmlhttp.status = = 400) {//or it can be any status code that starts with 4
    //gracefully handles the error
  }
};
Establishes the connection
Xmlhttp.open ("Get", "Http://myserver/api", true);
Initiate request
xmlhttp.send ();

This is a tedious task for simple, commonly used and often repetitive tasks. If you want to reuse the above process, you should either encapsulate it or use a code base.

The Angularjs XHR API adheres to an interface that is commonly referred to as promise. Because XHR is a method that is invoked asynchronously, the response of the server side is returned at some uncertain point in the future (we want it to return immediately). The Promise interface provides a way to handle this response and allows promise users to use it in a predictable manner.

For example, we want to get a user's information from the server, assuming that the backend interface used to accept the request is located on the/api/user path, and this interface can accept an id attribute as the URL parameter, then an example of how to initiate a XHR request using the angular core $http service is as follows:

$http. Get (' Api/user ', {params: {id: ' 5 '}
}). Success (function (data, status, headers, config) {
  //load successful after doing something
}). Error (function (data, status, headers, config) {
  //processing error
});

If you are a jquery user, you should find that Angularjs and jquery are very similar to the processing of asynchronous requests.

The $http.get method used in the above example is one of the many shortcuts provided by Angularjs's core service $http. Similarly, if you want to use ANGULARJS to send a POST request to the same URL along with some post data, you can do this as follows:

var postdata = {text: ' Long blob of text '};
The following line is appended to the URL as a parameter, so the POST request will eventually become/api/user?id=5
var config = {params: {id: ' 5 '}};
$http. Post (' Api/user ', postdata, config
). Success (function (data, status, headers, config) {
  //do something after success
}). Error (function (data, status, headers, config) {
  //processing error
});

For most commonly used request types, there are similar shortcuts, which include:, POST, DELETE, put, JSONP.

I. Further configuration requests

Although standard requests are simpler to use, there are sometimes drawbacks that can be misconfigured. If you want to achieve these things you will encounter difficulties:

A. Add some authorization headers to the request.
B. Modify how the cache is handled.
C. In some special way to transform the sent out of the request, or to transform the received response.

In these cases, you can pass an optional configuration object to the request for a deep configuration of the request. In the previous example, we used the Config object to specify an optional URL parameter. But the get and post methods there are shortcuts. Examples of method calls after this depth simplification are as follows:

$http (config)

The following is a basic pseudocode template used to invoke the previous method:

$http ({
  method:string,
  url:string,
  params:object,
  data:string or object,
  Headers:object,
  transformrequest:function transform (data, headersgetter) or an array of functions,
  Transformresponse: function transform (data, headersgetter) or an array of functions,
  Cache:boolean or Cache object,
  Timeout:numbe R,
  Withcredentials:boolean
});

Get, post, and other shortcuts automatically set the method parameter, so you don't need to set it manually. The Config object is passed to $http.get and $http.post as the last argument, so you can use this parameter within all shortcut methods. You can pass the Config object to modify the sent Request, Config object can set the following key values.

Method: A string that represents the type of HTTP request, such as Get or post.
Url:url string that represents the absolute or relative resource path of the request.
Params: A key and value are strings of objects (exactly a map) that represent the keys and values that need to be converted to URL parameters. For example:

[{key1: ' value1 ', Key2: ' value2 '}]

will be converted into

? key1=value&key2=value2

and will be appended to the URL. If we use a JS object (instead of a string or value) as a value in the map, the JS object is converted to a JSON string.

Data: A string or object that is sent as a request data.
Timeout: The number of milliseconds to wait before the request times out.

Two. Set HTTP headers

ANGULARJS has some default request headers, and these default request header information is provided on all requests made by angular. The default request headers include the following two:

1.accept:appliction/json,text/pain,/
2.x-requested-with:xmlhttprequest

If you want to set a special request header, you can do it in the following two ways.

The first method, if you want to set the request header to each sent out request, then you can set the special request to use the header to Angularjs default values. These values can be set through the $httpprovider.defaults.headers configuration object, which is usually done in the configuration section of the application. So, if you want to use "Do not TRACK" headers on all get requests, and delete Requested-with headers for all requests, you can simply manipulate the following:

Angular.module (' MyApp ', []).
  Config (function ($httpProvider) {
    //delete angularjs default X-request-with header
    Delete $ httpprovider.default.headers.common[' X-requested-with '];
    Set do not TRACK
    $httpProvider. default.headers.get[' DNT ' = ' 1 ';} for all get requests
;

If you only want to set the request headers for certain requests, but do not use them as defaults, then you can pass the header information to the $http service as part of the configuration object. Similarly, custom header information can be passed as part of the second argument to get requests, and the second parameter can also accept URL parameters.

$http. Get (' Api/user ', {
   //Set Authorization (authorization) header. In real applications, you need to go to a service to get the Auth token
   headers: {' Authorization ': ' Basic Qzsda231231 '},
   params: {id:5}
}). Success (function () {//process successful condition});

Three. Cache response

For HTTP GET requests, ANGULARJS provides a simple, out-of-the-box caching mechanism. It is not available by default for all request types, and you need to do some configuration to enable caching:

$http. Get (' Http://server/myapi ', {
  cache:true
}). Success (function () {//process successful condition});

This allows caching to be enabled, and then ANGULARJS will cache the response from the server. The next time you send a request to the same URL, Angularjs will return the response content in the cache. Caching is also smart, so even if you send multiple mock requests to the same URL, the cache will only send a request to the server, and the content of the response will be distributed to all requests after receiving a response from the service side.

However, this is somewhat impractical because the user first sees the old cache results and then sees the new results popping up. For example, when a user is about to click on a piece of data, it may suddenly change.

Note that, essentially, the response, even if it is read from the cache, is still asynchronous. In other words, the first time you make a request, you should encode it using the process of processing an asynchronous request.

Four. Conversion requests and responses

For all requests made through the $http service and received responses, ANGULARJS will perform some basic transformations, including the following.

1. Conversion request

If the requested configuration object attribute contains a JS object, the object is serialized into JSON format.

2. Conversion response

If the XSRF (Cross Site request forgery is detected, which means a cross station solicitation forgery, which is a way of a cross-site scripting attack), it is discarded directly. If a JSON response is detected, it is deserialized using the JSON parser.

If you don't need some of these transformations, or if you want to transform yourself, you can pass in your own function in the configuration item. These functions obtain the Request/response body of HTTP and the protocol header information, and then output the serialized, modified version. These conversion functions can be configured using Transformlrequest and transformresponse as keys, and these functions are configured with the $httpprovider service in the config function of the module.

When do we need to use these things? Let's say we have a service that's better suited to work with jquery. Post data uses the form Key1=val1&key2=val2 (that is, a string) instead of {key1:val1, Key2:val2}json format. We can do this in each request, or we can add a separate transformrequest call, and for the current example, we're going to add a generic transformrequest, This translates from JSON to string for all requests made. Here's how it's implemented:

var module = angular.module (' myApp ');
Module.config (function ($httpProvider) {
  $httpProvider. defaults.transformrequest = function (data) {
     // Use the Param method of jquery to convert the JSON data into a string form return
     $.param (data);}
);

Actual column configuration:

In use found that the background program is still unable to parse angular submitted data, compared to find the head missing ' X-requested-with '

So add in the configuration:

Copy Code code as follows:
$httpProvider. defaults.headers.post[' x-requested-with '] = ' XMLHttpRequest '

The partial configuration code that is attached to the test below:

Angular.module (' app ', [' nganimate ', ' ngcookies ', ' ngresource ', ' ngroute ', ' ngsanitize ', ' Ngtouch '],function ($httpProvider)
  {//Head configuration $httpProvider. defaults.headers.post[' content-type '] = ' application/x-www-form-urlencoded;charset=utf-8 '; $httpProvider. defaults.headers.post[' Accept '] = ' Application/json, Text/javascript, */*;
  q=0.01 ';
  $httpProvider. defaults.headers.post[' x-requested-with '] = ' xmlhttprequest '; /** * Rewrite the Param method of the angular, so that the angular uses jquery as the data serialization method of the workhorse;
   Converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */var param = function (obj) {var query = ', name, value, FULLSUBN
    Ame, SubName, Subvalue, innerobj, I;
      for (name in obj) {value = Obj[name];
          if (value instanceof Array) {for (i = 0; i < value.length; ++i) {subvalue = Value[i];
          Fullsubname = name + ' [' + i + '] ';
          Innerobj = {}; Innerobj[fullsubname] = SubValue;
        Query + + param (innerobj) + ' & ';
          } else if (value instanceof Object) {for (subname in value) {subvalue = Value[subname];
          Fullsubname = name + ' [' + SubName + '] ';
          Innerobj = {};
          Innerobj[fullsubname] = Subvalue;
        Query + + param (innerobj) + ' & '; } else if (value!== undefined && value!== null) query + = encodeURIComponent (name) + ' = ' +
    encodeURIComponent (value) + ' & '; Return query.length?
  Query.substr (0, query.length-1): query;
  }; Override $http Service ' s default transformrequest $httpProvider. defaults.transformrequest = [function (data) {RE Turn angular.isobject (data) && String (data)!== ' [Object File] '?
  Param (data): data;
}];
        }. config (function ($routeProvider) {$routeProvider. When ('/', {templateurl: ' views/main.html '), Controller: ' Mainctrl '}). When ('/about ', {
        Templateurl: ' views/about.html ', controller: ' Aboutctrl '}. Otherwise ({redirectto:
  '/'
      });

 });

I hope this article will help you with ANGULARJS programming.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.