编辑中,尚未完稿。。。2017.7.14 1345
很多前端开发出来的HTML5可能对于后台开发者来说,并不是很清楚,也许像我一样一知半解。而且真的让人很糊涂的地方就是前端的JS如何与后端的数据库进行双向通信,交互数据。
一种解释认为简单点说,这就是前端技术与后端技术沟通,根据业务定义交互接口,交互接口的的形式可能包含:
1、后端将数据输出到HTML页面,在JS控制逻辑中需要访问数据时可以从HTML中取得。
2、定义前后端请求的接口,一般是AJAX接口,如果存在跨域问题或一些特殊的业务场景,可能也会使用JSONP或者其他方式,总之,不论是何种方式请求,目的都是动态的请求数据,然后根据返回数据刷新页面内容。返回数据的格式现在主流是使用JSON格式,但是也不排除一些特殊的业务场景需要是使用XML或其他格式的数据。
对于我一样的新手,跨域请求的例子可参考Ajax 跨域请求、如何解决ajax跨域问题(转)。
总之非跨域请求限制比较少,但跨域请求的限制很多。
最初XHR
对象是不能跨域的,但新版本的浏览器允许跨域,但需要服务端对当前网站开权限。
在不允许跨域的年代,都是通过某些hack
的方法来实现跨域的。通常是借助一些天生能够跨域的元素:script, img, iframe
,这些元素里面script
最好,因为可以很方便地执行JS代码,从而能够对返回的数据进行处理。
跨域的优势是能充分利用分布式集群系统,使某些服务压力可以分散到多台服务器上。但数据交互的安全性上有一定影响。
不跨域的优势是前台页面和后台服务都在一个服务器下,安全性高,但但不能分摊负载。
目前计算机行业正在向高集成,多并发,低耦合的方向发展。所有基础服务以接口的方式提供是很好的一种方案(像百度地图,微信,支付宝都有服务接口),基础服务和中间件之间的交互也可能采用服务调用的方式,这些问题就牵扯到跨域,处理好跨域和安全的平衡点是这类集成系统的需要重点权衡的方面之一。
现在的互联网技术发展的越来越快,我们在开发过程中遇到的问题也越来越多。比如当我们需要进行跨域访问数据的时候该如何进行开发?本篇博文就记述如何使用Ajax进行跨域访问调用数据。
1、非跨域调用
我们用到的最多是这样的方式,也就是非跨域的进行访问,只是简单的在我们的网页中进行Ajax使用即可。如下面代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**
* 非跨域请求方式
*/
function
feikuayu() {
$.ajax({
type:
"post"
,
url: platformUrl +
"/security/modifyPwd"
,
data: $(
'#updatepwdform'
).serialize(),
dataType:
"json"
,
success:
function
(data) {
$(
"#updatepwd_btn"
).click();
$.toast(
"修改成功,系统即将退出,请重新登录"
, 1500);
},
error:
function
() {
$.toast(
"网络异常"
, 1500);
}
});
}
|
2、跨域请求
在我们进行跨域请求时需要改变ajax固定参数:
dataType:"jsonp",
crossDomain:true,
jsonpCallback:"jsonpCallbackFun",
jsonp:"callback",
且后台返回的数据格式必须是:jsonpCallbackFun(json数据); 这里的jsonpCallbackFun是你自定义的回调函数方法名。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/**
* 跨域请求方式
*/
function
kuayu() {
$.ajax({
type:
"post"
,
url: platformUrl +
"/security/modifyPwd"
,
data: params,
dataType:
"jsonp"
,
crossDomain:
true
,
jsonpCallback:
"jsonpCallbackFun"
,
jsonp:
"callback"
,
success:
function
(data) {
if
(data.result == 1) {
$(
"#updatepwd_btn"
).click();
$.toast(
"修改成功,系统即将退出,请重新登录"
, 1500);
setTimeout(
"logout()"
, 1600);
}
else
if
(data.result == 2) {
$.toast(data.msg, 1500);
}
else
{
$.toast(
"修改失败"
, 1500);
}
},
error:
function
() {
$.toast(
"网络异常"
, 1500);
}
});
}
|
两种协议类型
SOAP
我们知道Android网络通信的方式有两种:基于Socket和基于HTTP。基于HTTP又包括两种编程方式:HttpUrlConnection和HttpClient。
HttpURLConnection和SOAP完全是两回事,前者是网络编程方式(发送请求、获得应答),后者是一种数据传输协议,由于其基于XML,可以穿越防火墙,所以在Web Service中大受欢迎。
当比较HttpURLConnection与之之间的区别时,可以得知:
二者区别是,HttpURLConnection实现网络连接数据传输,SOAP以XML方式定义传输的数据格式(当然SOAP不光光定义数据格式,还包括方法、消息很多格式)。
其实将HTTP和SOAP放在一起比较更有意义,借用网络上的一段文字:
不同:都是底层的通信协议,请求包的格式不同而已,soap包是XML格式,http纯文本格式。
关系:SOAP是个通信协议, SOAP在HTTP协议的基础上,把编写成XML的REQUEST参数, 放在HTTP BODY上提交个WEB SERVICE服务器(SERVLET,ASP什么的) 处理完成后,结果也写成XML作为RESPONSE送回用户端, 为了使用户端和WEB SERVICE可以相互对应,可以使用WSDL作为这种通信方式的描述文件,利用WSDL工具可以自动生成WS和用户端的框架文件,SOAP具备把复杂对象序列化捆绑到XML里去的能力。
其实SOAP最早是针对RPC的一种解决方案,简单对象访问协议,很轻量,同时作为应用协议可以基于多种传输协议来传递消息(Http,SMTP等)。但是随着SOAP作为WebService的广泛应用,不断地增加附加的内容,使得现在开发人员觉得SOAP很重,使用门槛很高。在SOAP后续的发展过程中,WS-*一系列协议的制定,增加了SOAP的成熟度,也给SOAP增加了负担。
REST
REST其实并不是什么协议也不是什么标准,而是将Http协议的设计初衷作了诠释,在Http协议被广泛利用的今天,越来越多的是将其作为传输协议,而非原先设计者所考虑的应用协议。SOAP类型的WebService就是最好的例子,SOAP消息完全就是将Http协议作为消息承载,以至于对于Http协议中的各种参数(例如编码,错误码等)都置之不顾。其实,最轻量级的应用协议就是Http协议。Http协议所抽象的get,post,put,delete就好比数据库中最基本的增删改查,而互联网上的各种资源就好比数据库中的记录(可能这么比喻不是很好),对于各种资源的操作最后总是能抽象成为这四种基本操作,在定义了定位资源的规则以后,对于资源的操作通过标准的Http协议就可以实现,开发者也会受益于这种轻量级的协议。
自己理解的将REST的思想归结以下有如下几个关键点:
1.面向资源的接口设计
所有的接口设计都是针对资源来设计的,也就很类似于我们的面向对象和面向过程的设计区别,只不过现在将网络上的操作实体都作为资源来看待,同时URI的设计也是体现了对于资源的定位设计。后面会提到有一些网站的API设计说是REST设计,其实是RPC-REST的混合体,并非是REST的思想。
2.抽象操作为基础的CRUD
这点很简单,Http中的get,put,post,delete分别对应了read,update,create,delete四种操作,如果仅仅是作为对于资源的操作,抽象成为这四种已经足够了,但是对于现在的一些复杂的业务服务接口设计,可能这样的抽象未必能够满足。其实这也在后面的几个网站的API设计中暴露了这样的问题,如果要完全按照REST的思想来设计,那么适用的环境将会有限制,而非放之四海皆准的。
3.Http是应用协议而非传输协议
这点在后面各大网站的API分析中有很明显的体现,其实有些网站已经走到了SOAP的老路上,说是REST的理念设计,其实是作了一套私有的SOAP协议,因此称之为REST风格的自定义SOAP协议。
4.无状态,自包含
这点其实不仅仅是对于REST来说的,作为接口设计都需要能够做到这点,也是作为可扩展和高效性的最基本的保证,就算是使用SOAP的WebService也是一样。
参考文章