锁定老帖子 主题:给Ajax技术初学者的一些建议
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-14
dlee 写道 只用GET和POST方法主要的问题是会使得设计更加复杂。我今天刚好与朋友讨论过这个问题,就来说一下。
假设我在服务器端有一个订单的资源,英文就是order。我为这个资源定义了一个抽象的URI: http://www.xxx.com/order 如果我只使用GET和POST方法,我就需要在这个资源后面添加额外的参数来告诉服务器我要做什么,例如: 添加一个新的order(POST方法): http://www.xxx.com/order?action=add¶m1=value1¶m2=value2 (注意:上面只是示意,实际上这是GET方法的写法,其他几个方法参数编码不是直接放在URL中,以下类似) 获得一个id为12345的order(GET方法): http://www.xxx.com/order/12345 修改一个id为12345的order(POST方法): http://www.xxx.com/order/12345?action=update¶m1=value1¶m2=value2 删除一个id为12345的order(POST方法): http://www.xxx.com/order/12345?action=delete 如果我同时使用GET/POST/PUT/DELETE 4种方法,我就可以省掉上面的action参数。 添加一个新的order(PUT方法): http://www.xxx.com/order?param1=value1¶m2=value2 获得一个id为12345的order(GET方法): http://www.xxx.com/order/12345 修改一个id为12345的order(POST方法): http://www.xxx.com/order/12345?param1=value1¶m2=value2 删除一个id为12345的order(DELETE方法): http://www.xxx.com/order/12345 可以根据方法本身的语义来执行相关的操作(在Servlet API中就是doPut、doGet、doPost、doDelete)。 只要将服务器端建模为一系列的资源,上面4种方法代表着对这些资源所做的CRUD操作,这4种操作是完备的。 另外REST非常强调HTTP操作的语义对于中间组件的可见性,因为这会极大提高中间组件缓存的效率。同时采用4种HTTP方法,可以提高HTTP操作的可见性。 这个也不完全对,实际上暗含了两项资源:一项是订单集合orders,一项是某个特定的订单项order: 协议 URI 解释 --------------------------------------------------------------------------------------- GET /orders 显示资源订单集合的信息,可以跟一些参数,例如分页 /orders/page/3 POST /orders 添加一项订单 GET /orders/1 显示资源订单1的信息 PUT /orders/1 修改资源订单1的信息 DELETE /orders/1 删除资源订单1 |
|
返回顶楼 | |
发表时间:2007-05-14
robbin 写道 这个也不完全对,实际上暗含了两项资源:一项是订单集合orders,一项是某个特定的订单项order:
对的,是有一个orders的资源,我写的有问题。在初次创建一个新的order时,因为没有id,所以要提交给这个orders资源。 http://www.xxx.com/orders/12345 是orders的一个更加具体的子资源。 |
|
返回顶楼 | |
发表时间:2007-05-14
robbin 写道
如我设计b/s的MIS系统,我不认为rest风格有多少好处,反而基本很难实现。 而我要做一服务性网站,rest可能选择不错。 我只认为这两句说的有写含糊,其他和你表述的差别大吗?可能是我表达能力差。 举个例子,javaeye博客里 分类排序和分类名称 修改,用rest url怎么表达? 我把这类操作当成复杂的业务应用,在我眼中,动作大于资源。 当然用soap远程调用是没必要的。 另 rest是 与传统的 jsp,request,responseMVC竞争? 与 soap,hession,rmi,ebj等也竞争? 声明初哥一个。 ![]() |
|
返回顶楼 | |
发表时间:2007-05-14
radar 写道 robbin 写道
如我设计b/s的MIS系统,我不认为rest风格有多少好处,反而基本很难实现。 而我要做一服务性网站,rest可能选择不错。 我只认为这两句说的有写含糊,其他和你表述的差别大吗?可能是我表达能力差。 举个例子,javaeye博客里 分类排序和分类名称 修改,用rest url怎么表达? 我把这类操作当成复杂的业务应用,在我眼中,动作大于资源。 当然用soap远程调用是没必要的。 另 rest是 与传统的 jsp,request,responseMVC竞争? 与 soap,hession,rmi,ebj等也竞争? 声明初哥一个。 ![]() 协议 URI 解释 ------------------------------------------------------------------------- GET /blogs/2/categories/1 某个博客用户的第1个分类资源 GET /blogs/2/categories;sort 对某个博客用户的分类资源进行排序 PUT /blogs/2/categories/1 修改某个博客用户的第1个分类资源信息 这个例子带有嵌套资源,博客是一项资源,每个博客里面还嵌套了分类资源。 REST是一种架构方式,和Web Services是直接竞争关系,和MVC不构成竞争,例如你可以用MVC去实现REST。 REST的概念包含了很多含义在里面,例如: 1、REST是基于资源的,每一个URI就是一个独立的资源 上面已经演示了这一点,相对于web serivces的好处来说就是提供的服务根据资源进行了归类。 2、REST使用HTTP语义进行资源的操作,即GET/POST/PUT/DELETE,并且认为四种语义是完备的。 其中GET是对资源的只读性操作,不会引起资源状态的改变,POST/PUT/DELETE会引发资源状态的改变。相对于web services的好处就是极大降低了提供服务的复杂性,减少了服务组件的数量。如果说你使用web services要提供100个服务的话,使用REST,也许就只有20个服务需要提供。 3、REST提供的资源,是具有多种表象的,这个特性的实践意义非常大 例如GET /orders/1,返回的order信息是什么格式的呢?REST可以根据客户端的request请求header信息当中的Accept来决定返回信息的格式。 例如是浏览器请求/orders/1,那么REST Server就返回html页面 例如是手机请求/orders/1,那么REST Server就返回wap页面 例如是AJAX客户端请求/orders/1,那么REST Server就返回json数据 例如是某桌面应用程序通过web service方式去请求/orders/1,那么REST Server就返回xml数据 这一点当然非常有用了,它可以使得你开发的web应用同时支持浏览器,手机WAP,其他应用程序,AJAX等多种浏览方式。 |
|
返回顶楼 | |
发表时间:2007-05-15
robbin果然名不虚传,这么多。
robbin 写道 REST是一种架构方式,和Web Services是直接竞争关系,和MVC不构成竞争。 抛开ror,假如servlet,asp.net都很好的支持 rest 风格的各种方法。我们是不是设计web程序都向rest风格靠拢?有点影子需求的感觉,谁知道会不会有可能需要提供接口? 不过实现起来也不是很困难,可能前期设计上改变比较大。 soap我个人是很讨厌的! robbin 写道 REST使用HTTP语义进行资源的操作,即GET/POST/PUT/DELETE,并且认为四种语义是完备的。 这些 “语意” 只有"xmlhttp" 才能设置吗? 说实话,虽然偶很着迷ajax,但这样有点不舒服。 robbin 写道 例如是浏览器请求/orders/1,那么REST Server就返回html页面 例如是手机请求/orders/1,那么REST Server就返回wap页面 例如是AJAX客户端请求/orders/1,那么REST Server就返回json数据 例如是某桌面应用程序通过web service方式去请求/orders/1,那么REST Server就返回xml数据 REST可以根据客户端的request请求header信息当中的Accept来决定返回信息的格式。 到底这些“语意”怎么才能设置,专门的api啊? 不过html协议里的这点玩意都用上了。啊! 最后期待dlee早已翻译完成。 |
|
返回顶楼 | |
发表时间:2007-05-15
dlee 写道 winterwolf 写道 举个简单的例子就能打破完备性 比如加上查询条件 返回符合条件的order列表。
http://www.xxx.com/search/order?param1=value1¶m2=value2 如果不取消cgi参数当然可以了. 是那个说rest后边不加参数的 ? ![]() |
|
返回顶楼 | |
发表时间:2007-05-15
这样看rest好像是尽可能用url去暴露资源了
对于资源集合www.xxx.com/orders?.......的查询依然要采用cgi参数 对于部分资源www.xxx.com/order/123?.......的查询依然要采用cgi参数 这样的可能便于google搜索 但是对于安全性来说未必是好事 |
|
返回顶楼 | |
发表时间:2007-05-15
winterwolf 写道 如果不取消cgi参数当然可以了. 是那个说rest后边不加参数的?
你还是在断章取义啊。我以前说的是,是否带有CGI参数,并不是REST的本质特征。你先仔细看懂robbin后面的发言。 我上面写的这个URL还是有些问题,按照REST,写成 http://www.xxx.com/orders?param1=value1¶m2=value2 或者 http://www.xxx.com/orders/param1/value1/param2/value2 都是可以的。 winterwolf 写道 这样的可能便于google搜索 但是对于安全性来说未必是好事
又在胡说了,几乎就是在做FUD。REST风格架构设计最主要的关注点之一就是强化的安全性。在每一种架构风格中,实现安全的方法有所不同,你不能用一种思路去套另外一种思路。还是强烈建议你在对不同的架构风格进行对比之前,最好将Fielding的论文先仔细读一下。 |
|
返回顶楼 | |
发表时间:2007-05-15
我也谈谈我的看法。
1、对于iframe,不知道大家有没有注意,还是一样的存在兼容性bug,举个我遇到的问题: 生成一个iframe并载入一个新页面,在这个新页面中我循环发起一个异步连接,到服务器端取数据并显示,用来做实时监控。用户在父页面上可以关闭这个iframe,我通过将iframe元素从页面流中删除,按道理这样做的话里面的异步对象是可以一并被垃圾回收的,但实际上却大不一样:firefox里面和预期的一样,但是ie里面是不会自动回收的,我那个对象还在按我以前的要求,定时向服务器发起请求!也就是说,通过dom方法删除一个iframe,iframe内部存在的js对象在ie中是不会消失的,这有可能导致内存泄露!我们可以做这么一个实验,在父页面生成一个iframe,载入一个空白页面,为这个页面设置一个window.onclose函数,然后在父页面remove掉这个iframe,你会发现,ie并不会执行onclose函数,但ff正常。从上面看出,iframe也不像大家说的那样无懈可击,能用xmlhttp的地方还是用后者吧,要不然出一些莫名其妙的问题你还不知道怎么回事。 2、关于rest: 要实现rest风格的设计,使用ajax是最好的搭配。支持全功能的http协议不说,还能设置请求头,告诉服务器客户端需要什么样的数据格式,拿《ajax模式与最佳实践》里面的“置换模式”来说,这是必不可少的——服务器端得通过这个接受信息来生成并发送不同的表现,比如,浏览器需要html格式,而别的什么终端需要xml格式,等等等等,这样就做到了,同一个url(代表了唯一的资源)对于不同的终端,能够有不同的相应,按需发送。这里我想问一下,使用iframe,我如何来告知服务器,我的协议类型,以及接受的表现形式?这么看来,还是实用xmlhttp来的实在,您说呢? |
|
返回顶楼 | |
发表时间:2007-05-15
如果用http://www.xxx.com/orders/param1/value1/param2/value2
这样的url有什么好处? 它能代表资源吗 其他人能理解这样的url吗 ? robbin的意思我当然明白。 dlee不要用fielding的论文来压人 同样的东西不同的人有不同的理解。 我可以借用rest的思想但未必要遵循它。 “这样的可能便于google搜索 但是对于安全性来说未必是好事" 这话有什么不对的地方吗 ? rest不是google在暗地里宣传吗如果所有的web系统都采用web service那么google对他们就失效。 webservice和rest有不同的出发点 webservice强调如何获得信息而rest强调资源。 楼上有很多人谈到rest并不适合web商务系统的开发的直觉其实是正确的。rest和web service其实根本不是竞争关系 信息发布类的适合rest 信息处理类的适合web service. 当然我说的web service也不是ibm的那个套路 从书上是找不到的 |
|
返回顶楼 | |