转自:http://itindex.net/detail/50919-angularjs-%E6%9C%8D%E5%8A%A1%E5%99%A8-%E4%BA%A4%E4%BA%92

   对于AJAX应用(使用XMLHttpRequests)来说,向服务器发起请求的传统方式是:获取一个XMLHttpRequest对象的引用、发起请求、读取响应、检查状态码,最后处理服务端的响应。整个过程示例如下:

var xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange = function() {
if(xmlhttp.readystate == 4 && xmlhttp.status == 200) {
var response = xmlhttp.responseText;
}else if(xmlhttp.status == 400) { //或者可以是任何以4开头的状态码
//优雅地处理错误
}
}; //建立连接
xmlhttp.open("GET", "http://myserver/api", true); //发起请求
xmlhttp.send();

对于简单、常用而且会经常重复的任务来说,这是一种很烦琐的工作。如果你想复用以上过程,你应该进行封装或者使用代码库。

AngularJS XHR API遵守一种通常被称为Promise的接口。由于XHR是异步调用的方法,所以服务端的响应会在未来某个不确定的时间点上返回(我们希望它立即能返回)。Promise接口规定了处理这种响应的方式,并且允许Promise的使用者以一种可预见的方式来使用它。

例如,我们要从服务端获取一个用户的信息,假设用来接受请求的后台接口位于/api/user路径上,此接口可以接受一个id属性作为URL参数,那么使用Angular的核心$http服务发起XHR请求的方法示例如下:

$http.get('api/user', {params: {id:'5'}
}).success(function(data, status, headers, config) {
//加载成功之后做一些事
}).error(function(data, status, headers, config) {
//处理错误
});

如果你是jQuery使用者,你应该会发现,AngularJS和jQuery在对异步请求的处理方面非常类似。

上面例子中使用的$http.get方法是AngularJS的核心服务$http所提供的众多快捷方法之一。类似地,如果你想使用AngularJS向同一个URL发送POST请求,同时带上一些POST数据,你可以像下面这样做:

var postData = {text:'long blob of text'};
//下面这一行会被当成参数附加到URL后面,所以post请求最终会变成/api/user?id=5
var config = {params: {id: '5'}};
$http.post('api/user', postData, config
).success(function(data, status, headers, config) {
//成功之后做一些事情
}).error(function(data, status, headers, config) {
//处理错误
});

对于大多数常用的请求类型,都有类似的快捷方法,这些请求类型包括:GET、HEAD、POST、DELETE、PUT、JSONP。

一.进一步配置请求

虽然标准的请求方式使用起来比较简单,但是,有时候会存在可配置性不佳的缺点。如果你想要实现下面这些事情就会遇到困难:

a.给请求加上一些授权头。

b.修改对缓存的处理方式。

c.用一些特殊的方式来变换发送出去的请求,或者变换接收到的响应。

在这些情况下,你可以给请求传递一个可选的配置对象,从而对请求进行深度配置。在前面的例子中,我们使用config对象指定了一个可选的URL参数。但是那里的GET和POST方法是一些快捷方式。这种深度简化之后的方法调用示例如下:

$http(config)

下面是一个基本的伪代码模板,用来调用前面的这个方法:

$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: number,
withCredentials: boolean
});

GET、POST及其他快捷方法都会自动设置method参数,所以不需要手动设置。config对象会作为最后一个参数传递给$http.get和$http.post,所以,在所有的快捷方法内部都可以使用这个参数。你可以传递config对象来修改发送的请求,config对象可以设置以下键值。

method:一个字符串,表示HTTP请求的类型,例如GET或者POST。

url:URL字符串,表示请求的绝对或者相对资源路径。

params:一个键和值都是字符串的对象(确切来说是一个map),表示需要转换成URL参数的键和值。例如:

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

将会被转换成

?key1=value&key2=value2

并会被附加到URL后面。如果我们使用js对象(而不是字符串或者数值)作为map中的值,那么这个js对象会被转换成JSON字符串。

data:一个字符串或者对象,它会被当作请求数据发送。

timeout:在请求超时之前需要等待的毫秒数。

二.设置HTTP头

AngularJS带有一些默认的请求头,Angular发出的所有请求上都会带有这些默认的请求头信息。默认请求头包括以下两个:

1.Accept:appliction/json,text/pain,/

2.X-Requested-With: XMLHttpRequest

如果想设置特殊的请求头,可以用如下两种方法实现。

第一种方法,如果你想把请求头设置到每一个发送出去的请求上,那么你可以把需要使用的特殊请求头设置成AngularJS的默认值。这些值可以通过$httpProvider.defaults.headers配置对象来设置,通常会在应用的配置部分来做这件事情。所以,如果你想对所有的GET请求使用“DO NOT TRACK"头,同时对所有请求删除Requested-With头,可以简单地操作如下:

angular.module('MyApp', []).
config(function($httpProvider) {
//删除AngularJS默认的X-Request-With头
delete $httpProvider.default.headers.common['X-Requested-With'];
//为所有GET请求设置DO NOT TRACK
$httpProvider.default.headers.get['DNT'] = '1';
});

如果你只想对某些特定的请求设置请求头,但不把它们作为默认值,那么你可以把头信息作为配置对象的一部分传递给$http服务。同样的,自定义头信息也可以作为第二个参数的一部分传递给GET请求,第二个参数还可以同时接受URL参数。

$http.get('api/user', {
//设置Authorization(授权)头。在真实的应用中,你需要到一个服务里面去获取auth令牌
headers: {'Authorization': 'Basic Qzsda231231'},
params: {id:5}
}).success(function() {//处理成功的情况 });

三.缓存响应

对于HTTP GET请求,AngularJS提供了一个开箱即用的简单缓存机制。默认情况下它对所有请求类型都不可用,为了启用缓存,你需要做一些配置:

$http.get('http://server/myapi', {
cache: true
}).success(function() {//处理成功的情况});

这样就可以启用缓存,然后AngularJS将会缓存来自服务器的响应。下一次向同一个URL发送请求的时候,AngularJS将会返回缓存中的响应内容。缓存也是智能的,所以即使你向同一个URL发送多次模拟的请求,缓存也只会向服务器发送一个请求,而且在收到服务端的响应之后,响应的内容会被分发给所有请求。

但是,这样做有些不太实用,因为用户会先看到缓存的旧结果,然后看到新的结果突然出现。例如,当用户即将点击一条数据时,它可能会突然发生变化。

注意,从本质上来说,响应(即使是从缓存中读取的)依然是异步的。换句话说,在第一次发出请求的时候,你应该使用处理异步请求的方式来编码。

四.转换请求和响应

对于所有通过$http服务发出的请求和收到的响应来说,AngularJS都会进行一些基本的转换,包括如下内容。

1.转换请求

如果请求的配置对象属性中包含JS对象,那么就把这个对象序列化成JSON格式。

2.转换响应

如果检测到了XSRF(Cross Site Request Forgery的缩写,意为跨站请求伪造,这是跨站脚本攻击的一种方式)前缀,则直接丢弃。如果检测到了JSON响应,则使用JSON解析器对它进行反序列化。

如果你不需要其中的某些转换,或者想自已进行转换,可以在配置项里面传入自已的函数。这些函数会获取HTTP的request/response体以及协议头信息,然后输出序列化、修改之后的版本。可以使用transformLRequest和transformResponse作为key来配置这些转换函数,而这两个函数在模块的config函数中是用$httpProvider服务来配置的。

我们什么时候需要使用这些东西呢?假设我们有一个服务,它更适合用jQuery的方式来操作。POST数据使用key1=val1&key2=val2(也就是字符串)形式来代替{key1:val1, key2:val2}JSON格式。我们可以在每个请求中来进行这种转换,也可以添加一个独立transformRequest调用,对于当前这个例子来说,我们打算添加一个通用的transformRequest,这样所有发出的请求都会进行这种从JSON到字符串的转换。下面就是实现方式:

var module = angular.module('myApp');

module.config(function($httpProvider) {
$httpProvider.defaults.transformRequest = function(data) {
//使用jQuery的param方法把JSON数据转换成字符串形式
return $.param(data);
};
});

AngularJS与服务器交互(4)的更多相关文章

  1. AngularJs与Java Web服务器交互

    AngularJs是Google工程师研发的产品,它的强大之处不是几句话就能描述的,只有真正使用过的人才能体会到,笔者准备在这篇文章中,以一个简单的登录校验的例子说明如何使用AngularJs和Web ...

  2. 从高处理解android与服务器交互(看懂了做开发就会非常的容易)

    今天帮一个朋友改一个bug 他可以算是初学者吧 .我给他看了看代码,从代码和跟他聊天能明显的发现他对客户端与服务器交互 基本 不是很了解.所以我花了更多时间去给他讲客户端与服务器的关系.我觉得从这个高 ...

  3. 跟服务器交互的Web表单(form)

    使用HTML来构建可以跟服务器交互的Web表单(form),通过给你的form元素添加一个action属性来达到此目的. action属性的值指定了表单提交到服务器的地址. 例如: <form ...

  4. Android和FTP服务器交互,上传下载文件(实例demo)

    今天同学说他备份了联系人的数据放在一个文件里,想把它存到服务器上,以便之后可以进行下载恢复..于是帮他写了个上传,下载文件的demo 主要是 跟FTP服务器打交道-因为这个东东有免费的可以身亲哈 1. ...

  5. html name id, 与服务器交互必须有name

    html name id, 与服务器交互必须有name 在HTML中元素的ID和Name的区别和联系. 今天写了个测试,在php脚本里怎么也获取不到$_POST['userName']的值,经检查在h ...

  6. 20171018 微信小程序客户端数据和服务器交互

    -- 时常在想,怎么样才能把知识写的清晰,其实是我理解的不够清晰 微信小程序其实是一个客户端页面,也是需要和服务器交互才能体现数据. 1 --服务器搭建Web API :MVC4 中的一个模板, 如下 ...

  7. 浏览器与服务器交互原理以及用java模拟浏览器操作v

    浏览器应用服务器JavaPHPApache * 1,在HTTP的WEB应用中, 应用客户端和服务器之间的状态是通过Session来维持的, 而Session的本质就是Cookie, * 简单的讲,当浏 ...

  8. ASP.NET 表单验证方法与客户端(浏览器)服务器交互机制的故事

    想到这个问题完全是一个意外吧,是在寻找另外一个问题答案的过程中,才对验证方法与浏览器服务器交互机制的关系有了清晰的认识. 先说下验证方法,验证方法分为前台验证和后台验证. 前台验证就是类似jQuery ...

  9. 利用ajax短轮询+php与服务器交互制作简易即时聊天网站

    主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Server-sent Events). 本文主要介绍ajax短轮询的简易实现方式. 看懂此文 ...

随机推荐

  1. 出让执行权:Task.Yield, Dispathcer.Yield

    Yield 这个词很有意思,叫做“屈服”“放弃”“让步”,字面意义上是让出当前任务的执行权,转而让其他任务可以插入执行.Task.Dispatcher.Thread 都有 Yield() 方法,看起来 ...

  2. Java8新特性——StreamAPI(一)

    1. 流的基本概念 1.1 什么是流? 流是Java8引入的全新概念,它用来处理集合中的数据,暂且可以把它理解为一种高级集合. 众所周知,集合操作非常麻烦,若要对集合进行筛选.投影,需要写大量的代码, ...

  3. LeetCode String Compression

    原题链接在这里:https://leetcode.com/problems/string-compression/description/ 题目: Given an array of characte ...

  4. 【java多线程】用户线程和守护线程的区别

    java中线程分为两种类型:用户线程和守护线程.通过Thread.setDaemon(false)设置为用户线程:通过Thread.setDaemon(true)设置为守护线程.如果不设置次属性,默认 ...

  5. SmartFoxServer资料

    http://blog.sina.com.cn/s/blog_6bc2090c0100pgkx.html http://www.cnblogs.com/winson-w/p/3555106.html ...

  6. 虚拟路由冗余协议VRRP

    一.VRRP简介 虚拟路由冗余协议VRRP(Virtual Router Redundancy Protocol)通过把几台路由设备联合组成一台虚拟的路由设备,将虚拟路由设备的IP地址作为用户的默认网 ...

  7. 安装xamp之后,appach、mysql等问题的总结

    问题一:无法启动的问题 如果他们无法启动,大多数情况是端口号被占用. 首先就是查看端口号:点击“netstart“按钮查看端口号的使用详情 如果被占用就点击"config”按钮,进行端口号的 ...

  8. golang的指针到string,string到指针的转换

    由于某个需求,需要如题的转换,废话不多说,直接贴代码了,其实挺丑了,备用了 func (this *Server) socketParserHandler(client *genTcpServer.C ...

  9. Js中常用的字符串,数组,函数扩展

    由于最近辞职在家,自己的时间相对多一点.所以就根据prototytpeJS的API,结合自己正在看的司徒大神的<javascript框架设计>,整理了下Js中常用一些字符串,数组,函数扩展 ...

  10. Java运算符,算术运算符

    算术运算符介绍 算术运算符用在数学表达式中,它们的作用和在数学中的作用一样. 下表列出了所有的算术运算符. 表格中的实例假设整数变量A的值为10,变量B的值为20: 操作符 描述 例子 + 加法 - ...