2015年2月5日 星期四

$http的介紹及使用

在AngularJS中,$http是用來做Ajax的功能. 以下會談到$http及$httpProvider.




參考書: Novice to Ninja book: Understanding the $http Service, page-160

1. 參數及關鍵字
1.1 [config]: (https://docs.angularjs.org/api/ng/service/$http#get)
Usage
$http(config);

Arguments
Param Type Details
config object
Object describing the request to be made and how it should be processed. The object has following properties:

method – {string} – HTTP method (e.g. 'GET', 'POST', etc)
url – {string} – Absolute or relative URL of the resource that is being requested.
params – {Object.<string|Object>} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.
data – {string|Object} – Data to be sent as the request message data.
headers – {Object} – Map of strings or functions which return strings representing HTTP headers to send to the server. If the return value of a function is null, the header will not be sent. Functions accept a config object as an argument.
xsrfHeaderName – {string} – Name of HTTP header to populate with the XSRF token.
xsrfCookieName – {string} – Name of cookie containing the XSRF token.
transformRequest – {function(data, headersGetter)|Array.<function(data, headersGetter)>} – transform function or an array of such functions. The transform function takes the http request body and headers and returns its transformed (typically serialized) version. See Overriding the Default Transformations
transformResponse – {function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>} – transform function or an array of such functions. The transform function takes the http response body, headers and status and returns its transformed (typically deserialized) version. See Overriding the Default Transformations
cache – {boolean|Cache} – If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching.
timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.
withCredentials - {boolean} - whether to set the withCredentials flag on the XHR object. See requests with credentials for more information.
responseType - {string} - see requestType.

---
1.2 headers
物件型態,用來設定http request header.
---
1.3 method
GET/DELETE/HEAD/JSONP/POST/PUT
---
1.4 data (POST/PUT會用到), 物件型態

====================================
GET
//語法:
$http.get(url, [config])
//Example
$http.get('/api/users.json');
$http.get('/customers/customerId');

另一種方式
$http({url:'http://api.openweathermap.org/data/2.5/weather', method:'GET', headers:{'Content-Type' : 'json'}, params:{q: "Taipei,Taiwan"}})

---
POST
//語法:
$http.post(url,data,[config])

//http://hello-angularjs.appspot.com/angularjs-http-service-ajax-post-json-data-code-example
//範例
var dataObj = {
name : $scope.name,
employees : $scope.employees,
headoffice : $scope.headoffice
};
var res = $http.post('/savecompany_json', dataObj);

$http({
            url: 'http://samedomain.com/GetPersons',
            method: "POST",
            data: postData,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })

PROMISE
error (data, status, config, headers, statusText)

====================================
2. 一些其他的設定及討論主題

2.1 設定request headers
方法一: 設定global的http request headers
一旦設定好,每個http request header都會吃這個設定,舉例要設定只接收json格式的資料
angular
  .module('mainApp')
  .configure(function($httpProvider){
    $httpProvider.defaults.headers.common.Accept="applcation/json";
  });

方法二: 全域的改變client端可接收的格式
angular
  .module('mainApp')
  .run(function($http){
    $http.defaults.headers.common.Accept="applcation/json";
  });

方法三: 對POST或GET設定global的http request headers
angular
  .module('mainApp')
  .configure(function($httpProvider){
    $httpProvider.defaults.headers.get={'Content-Type':'application/json'};
});

方法四: 只對該次的http的get作設定
$http({url:'/api',method:'GET',headers:{'Content-Type':'text/plain'}});

---
2.2 使用$httpProvider的transformRequest和transformResponse來格式化傳出或接收資料的格式
影響: Global??
transformRequest: 將傳出去的資料作JSON stringify,並且設定Content-Type為text/plain
angular
  .module('mainApp',[])
  .config(function($httpProvider){
    $httpProvider.defaults.transformRequest=function(data,getHeaders){
        var headers=getHeaders(); //obtain the headers
        headers['Content-Type']='text/plain'; // add a header dynamically
        return JSON.stringify(data); //return serialized data
    }
  });

$http使用transformRequest
$http.({url:'/api',method:'GET',transformRequest:transformRequestFunc});

Note: 可以使用push/unshift可設定多種Request Transformers
$http.({url:'/api',method:'GET',transformRequest:transformRequestFunc});

--
transformResponse: 將接收的資料作JSON stringify
angular
  .module('mainApp',[]).config(function($httpProvider){
    $httpProvider.defaults.transformResponse=function(data,getHeaders){
        data.someProperty='something else'; //change the response
        Interacting with REST APIs 167
        return JSON.stringify(data); //return serialized data
    }
  });

---
2.3 Caching
利用cache參數設定取得的資料是否使用cache中的資料.
return $http.get('http://api.openweathermap.org/data/2.5/weather?'+ query,{cache:true});
所取得的資料會放在$cacheFactory中. 若要永久保存該資料,可將它存入localStorage.

---
2.4 interceptors(攔截器/遮斷器)
有點類似在做request/response前,攔截的動作會發生,然後可以作一些處理,不容易懂..
可參考(AngularJS ?截器和好棒例子: http://my.oschina.net/ilivebox/blog/290881)


Note: interceptors和http使用transformRequest/transformResponse的差異
transformRequest/transformResponse只能在送出請求或接收到回應時,僅對header和data作存取
,但interceptors可以對所有的request/response的內容作處理.

結論: $http/$httpProvider是低階的操作. 如果只是作CRUD, 可以使用$resource(建構於$http之上).

====================================
3. 使用.success/.error或使用回傳的promise (.then)
在so有找到一篇討論(http://stackoverflow.com/questions/16385278/angular-httppromise-difference-between-success-error-methods-and-thens-a)
其實兩者的差異在於:
3.1 .success/.error
傳統簡易的用法
.success(function(data, status, headers, config))
.error(function(data, status, headers, config))

3.2 使用promise物件
可以使用功能強大的promise物件(如.then())

====================================
其他參考資源/測試

測試url (Taipei%2CTaiwan = Taipei,Taiwan)
http://api.openweathermap.org/data/2.5/weather?q=Taipei%2CTaiwan
{params: {q: "Taipei,Taiwan"}}
params:這個關鍵字一定要加,而後面的資料就會轉成實際的參數
//範例
$http.get("http://api.openweathermap.org/data/2.5/weather"
          ,{params : {q: "Taipei,Taiwan"}});
       
====================================
其他參考書目
1. NG-Book: page157, Services

1 則留言:

  1. Excellent article. Very interesting to read. I really love to read such a nice article. Thanks! keep rocking.
    AngularJS Online Course Bangalore

    回覆刪除