本地HTML访问REST服务的实现
本地HTML訪問REST服務的實現
?
1 ??前言
最近一段時間在研究如何實現跨平臺應用,其中的一個關鍵技術點就是本地HTML頁面如何訪問遠程服務。經過探索,終于解決了碰到的各種問題,做出了一個Demo.?
本文就Demo所用的技術架構做了一個簡介,并分析了實現中碰到的問題及相應的解決方法。一來以此作為這段時間工作的一個技術總結,二來希望能對其他同行有所幫助。
2???????? 技術架構
Demo 本身的功能很簡單,
1)????? 本地HTML 發出 “POST” 命令,發送一段數據到 Server端
2)????? Server 端存儲收到的數據
3)????? 本地HTML? 發出工“GET” 命令,取回數據 ?
Demo分為兩部分。Client端比較簡單,就是HTML+JQuery. ?Server端則用REST服務, 是用JAVA寫的,具體方案是glasshfish+ Jersey.? 兩者這間用Json格式通信。
3???????? 主要問題的解決方法:
3.1?????? Same origin policy
3.1.1?????? 問題
這是整個Demo中耗時最多的一個問題。問題的表象是 從Chrome發出HTTP命令后,Chrome console中報 “Origin null?is not?allowed?by Access-Control-Allow-Origin”錯誤。
這是由于Browser的same origin policy 限制的緣故。簡單來說,從HTML中發出XMLHttpRequest ?請求時,Browser會做檢查,如果發現Response中沒有Access-Control-Allow-Origin Header或Access-Control-Allow-Origin Header Header的值與 HTML的 orgin 不同時,Browser會拒接絕該Response,Javascript就收不到該Response。 本地HTML的Origin是 null, 而Server端沒有發出Access-Control-Allow-Origin Header Header給Browser, ?所以會有了“Origin null?is not?allowed?by Access-Control-Allow-Origin”錯誤。
3.1.2?????? 解決方法
事實上有一個W3C標準,Cross Origin Resource Sharing (CORS) 專門用來解決這個問題的。目前的主流Browser也有支持。CORS 在HTTP Message 加入幾個Header, Browser和 Server可以利用這些Header來判斷對方是否是安全,是否可以通信。
具體來說,CORS包括兩方面。 Server端和Browser端。
3.1.2.1?????? Server端
以Demo中的Server端為例,解決方法就是在 Jersey Servlet中加入一個Filter, 在 Filter中修改給Browser的Response, 共有兩步
1)????? 配置Web.xml
在Jersey Servlet中加入init-param
<servlet>
??????? <servlet-name>ServletAdaptor</servlet-name>
??????? <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
??????? <init-param>
????????????? <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
???????????? <param-value>jasontesting.ResponseCorsFilter</param-value>
??????? </init-param>
??????? <load-on-startup>1</load-on-startup>
???????
</servlet>
?
2)????? ResponseCorsFilter
/*
?* To change this template, choose Tools | Templates
?* and open the template in the editor.
?*/
package jasontesting;
?
/**
?*
?* @author jianl
?*/
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
?
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
?
public class ResponseCorsFilter implements ContainerResponseFilter {
?
??? @Override
??? public ContainerResponse filter(ContainerRequest req, ContainerResponse contResp) {
?
??????? ResponseBuilder resp = Response.fromResponse(contResp.getResponse());
??????? resp.header("Access-Control-Allow-Origin", "*")
??????????????? .header("Access-Control-Max-Age", 1728000)
??????? .header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
?
??????? String reqHead = req.getHeaderValue("Access-Control-Request-Headers");
?
??????? if(null != reqHead && !reqHead.equals(null)){
??????????? resp.header("Access-Control-Allow-Headers", reqHead);
??????? }
?
??????? contResp.setResponse(resp.build());
??????????? return contResp;
??? }
?
}
3.1.2.2?????? Browser端
如前所述,Browser已經實現了CORS,CORS對應用開發人員是透明的。為了方便,公布Demo的Browser端源代碼如下。
<script src="jquery-latest.js"></script>
? <script src="jquery.json-2.3.js"></script>
<script type="text/javascript">
? var url= "http://localhost:8080/WebApplication3/resources/contact";
? var postobject={id:2,name:"Bob9",addresses:[{street:"Long Street 1",town:"Short Village"}],id_attribute:888};
?jQuery.ajax({
????? url: url,
????? type: "POST",
????? data: $.toJSON(postobject),
????? dataType: "json",
????? contentType:"application/json",
????? success: function(result) {
??????????????? ???? //Write your code here
??? ??????????? ??//alert(result);
??? ??????????? ??$.get(
??? ??????????????????????????????????????????? ????url,
??? ??????????????????????????????????????????? ????function(data, textStatus, jqXHR) {
??? ??????????????????????????????????????????? ??????????????? alert(data);
??? ??????????????????????????????????????????? ????},
??? ??????????????????????????????????????????? ????"json"
??? ??????????????????????????????????????????? );
????? }
});
? </script>
3.2?????? Accept and Content-Type Header
這個問題本身并不復雜,但由于之前對HTTP協議并不十分了解,還是花了大半天時間。問題核心是要在Request中要加入 Accept 與 Content-Type Header,指定可接愛的和發送的MIME 類型。具體的解決例子可參考Browser端的代碼。
4????????? 總結
經過這些天的摸索,終于做出這個Demo,弄清楚了本地HTML訪問REST服務可如何實現,心中很是欣慰。要繼續努力,深化在移動開發方面的技術積累。
5???????? 參考
?
http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
http://www.html5rocks.com/en/tutorials/cors/
http://blog.usul.org/cors-compliant-rest-api-with-jersey-and-containerresponsefilter/
轉載于:https://www.cnblogs.com/LevinJ/archive/2012/04/09/2439670.html
總結
以上是生活随笔為你收集整理的本地HTML访问REST服务的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一文读懂应用市场的[发展简史]
- 下一篇: HTML5小试 双人贪吃蛇