首页 > 网站 > WEB开发 > 正文

$http 服务

2024-04-27 14:20:33
字体:
来源:转载
供稿:网友

$http 服务

参考 :https://docs.angularjs.org/api/ng/service/$http

$http 是angular 封装好的 xmlHttPRequest 请求

内部还涉及到了

$httpBackend,$httpProvider,$q (angular的promise),$cacheFactory (angular的cache机制) 等等

angular 的思想偏向restful概念, 所以都有 GET,POST,PUT,DELTE,PATCH,HEAD 等

angular 默认的请求头

Accept: application/json, text/plain 接受json和text

Content-Type :application/json

如果要修改默认设置的话可以在app.config上做修改

var app = angular.module("app", []);app.config(function ($httpProvider) {               log(angular.toJson($httpProvider.defaults)); //可以看看其它默认    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; //我们常用的form     $httpProvider.defaults.headers.put["Content-Type"] = "application/x-www-form-urlencoded";    $httpProvider.defaults.headers.patch["Content-Type"] = "application/x-www-form-urlencoded";});

只要是default的headers,在每次发送请求的时候都会带上。

所以如果我们每个请求都有用到一些自定义的header,我们也可以写入在default.headers中

$httpProvider.defaults.headers.common["myHeader"] = "myheaderValue";//common 表示不管任何的 method POST,GET,PUT等

这些default的header是可以在每一次我们发请求的时候通过参数来覆盖掉.

另外$http service 也提供了一个defaults的指针 (注: $httpProvider.defaults === $http.defaults )

app.controller("ctrl", function ($scope, $http) {    $http.defaults.headers.common["myHeader"] = "abc";          });

$httpProvider.defaults.transformRequest& transformResponse

这是angular提供给我们的2个接口,在请求发送前和响应还没有触发callback前对post data 和 response data做一些处理

它们是个数组类型,我们可以push一些函数进去 (angular默认对request和response都放入了一个方法,post的时候如果data是对象将json化,响应时如果data是json类型,将解析成对象)

在每一次的请求,我们依然可以覆盖整个数组.

var app = angular.module("app", []);app.config(function ($httpProvider) {                $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";    $httpProvider.defaults.transformRequest.shift(); //把angular default的去掉    $httpProvider.defaults.transformRequest.push(function (postData) { //这个function不是依赖注入哦        if (angular.isObject(postData)) {             return $.param(postData); //如果postData是对象就把它转成param string 返回, 这里借用了jQuery方法        }        return postData;    });    $httpProvider.defaults.transformResponse.push(function (responseData) {        log(angular.toJson(responseData)); //响应的数据可以做一些处理        return "data";    });});app.controller("ctrl", function ($scope, $http) {    $http({        method: "POST",        url: "handle.ashx",        data: {            key: "value"        },        transformResponse: [], //每一次请求也可以覆盖default        transformResponse: $http.defaults.transformResponse.concat([function () { return "abc" }]) //如果default要保留要concat    }).success(function (responseData) {        log(responseData === "abc"); //true    });});

$httpProvider.defaults.cache

angular 默认cahce = false, 一样可以通过defaults去设置每个请求(当然只有GET请求可以cache)

我们也可以在每次请求覆盖设置

当同时发送2个没有缓存的请求时,angular也能处理,只发送一次(不错哦).

var app = angular.module("app", []);app.config(function ($httpProvider) {    $httpProvider.defaults.cache = true;          });app.controller("ctrl", function ($scope, $http) {    //并发但是只会发送一个请求    $http.get("handle.ashx");    $http.get("handle.ashx");         //我们可以为每次请求要不要使用缓存或者缓存数据    $http({        url: "handle.ashx",        method: "GET",        cahce: true    });    $http({        url: "handle.ashx",         method: "GET",        cache : false //强制不使用缓存,即使已存在    });});

$httpProvider.interceptors (interceptors 中文是拦截的意思)

除了之前介绍过的 transform 可以对数据做一些处理, angular也提供了另外4个时刻,分别是 onRequest, onRequestFail, onResponse, onResponseFail

让我们做一些而外处理. 比如当我们server返回500的时候,可能我们想做一个通用的alert,或是request fail 的话自动调整一下config在尝试请求等等.

    //interceptors是数组,放入的是可以依赖注入的方法哦!    $httpProvider.interceptors.push(["$q", function ($q) {        return {            request: function (config) { //config = {method, postData, url, headers} 等                                            return config; //返回一个新的config,可以做一些统一的验证或者调整等.            },            requestError: function (rejection) {                                      return $q.reject(rejection); //必须返回一个promise对象                                                          },            response: function (response) {                                     return response; //这里也可以返回 promise, 甚至是把它给 $q.reject掉            },            responseError: function (rejection) { //rejection = { config, data, status, statusText, headers }                                return $q.reject(rejection); //必须返回一个promise对象                              }        };    }]);

和 transform 的执行次序是这样的interceptors.request -> transformRequest -> transformResponse -> interceptors.response

安全问题 (JSON Vulnerability Protection &Cross Site Request Forgery (XSRF) Protection) 参考 :http://bijian1013.iteye.com/blog/2112233

json漏洞可以参考 :http://blog.roodo.com/rocksaying/archives/2955557.html

我个人没有理解很多,觉得只有jsonp可能引发此问题,但是jsonp一般都是非敏感数据,所以我就没认真对待了,高手可以提点我一下 ^^

XSRF 大家应该很熟悉了,参考 :http://blog.csdn.net/xcyuzhen/article/details/6255038

angular 对XSRF的防范是这样的,在第一次请求的时候服务器返回一个 "XSRF-TOKEN" 的cookie, 值是一个唯一的随机值,

那么之后每个$http请求都会附上一个 "X-XSRF-TOKEN" 的header, 值就是刚才那个随机数, 那么服务器可以做一个对比来确认身份。

这里给一个asp.net的例子

protected void Page_Load(object sender, EventArgs e){    if (!IsPostBack)    {        //当用户登入后, 访问页面        string ANGULAR_XSRF_COOKIE_KEY = "XSRF-TOKEN";        var token = session["pageToken"];        if (token == null)        {            string pageToken = Guid.NewGuid().ToString(); //随机数            Session["pageToken"] = pageToken;            Response.Cookies.Add(new HttpCookie(ANGULAR_XSRF_COOKIE_KEY)            {                Value = pageToken,                Expires = DateTime.Now.AddDays(1)  //配合前台logout洗掉               });        }    }}

$http请求基本上什么都不需要做

public void ProcessRequest (HttpContext context) {    string ANGULAR_XSRF_HEADER_KEY= "X-XSRF-TOKEN";    string pageToken = context.Request.Headers.Get(ANGULAR_XSRF_HEADER_KEY).ToString(); //从header提取    if(context.Session["pageToken"].ToString() == pageToken) //对比是否一直    {        //pass    }       context.Response.ContentType = "text/plain";    context.Response.Write(context.Request.ContentType + "123");}

更新 : 2015-05-08

$http 返回的是一个扩展了的 promise 对象

它有多了一些属性,比如 success , error (当然原本的then 还是有的)

success 和 then 是不太一样的,then 就是典型的promise实现啦,你返回另一个promise or value 它会串连下去,

但是 success 就不会,它只能算一个void,它的返回值是被忽视的。

success(function(data){}) , then(function(response){}) ; 前者的arguments 是response.data , 后者是整个 response 对象

$http({    url: "//localhost:14431/api/products",    method: "get"}).then(function (response) {     success.apply(window, [response.data, response.status, response.headers, response.config]); //大概是这样调用的    return response;});

所以用的时候要注意哦!


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表