使用Httpclient来替代客户端的jsonp跨域解决方案
最近接手一個(gè)項(xiàng)目,新項(xiàng)目需要調(diào)用老項(xiàng)目的接口,但是老項(xiàng)目和新項(xiàng)目不再同一個(gè)域名下,所以必須進(jìn)行跨域調(diào)用了,但是老項(xiàng)目又不能進(jìn)行任何修改,所以jsonp也無(wú)法解決了,于是想到了使用了Httpclient來(lái)進(jìn)行服務(wù)端的“跨域”來(lái)替代jsonp的客戶(hù)端跨域方案。
?
上一篇博文中,詳細(xì)剖析了jsonp的跨域原理,本文使用Httpclient來(lái)替代jsonp的客戶(hù)端跨域方案。
先去 http://hc.apache.org/downloads.cgi 下載最新版httpclient。解壓tutorial文件夾中有html和PDF的使用介紹。
下面實(shí)現(xiàn)從8888端口的html4項(xiàng)目中跨域訪問(wèn)8080端口的html5項(xiàng)目中的JsonServlet:
1)在html4中建立一個(gè)中間代理servelt和一個(gè)工具類(lèi),工具類(lèi)代碼如下:
import java.io.IOException; import java.io.OutputStream; import org.apache.http.HttpEntity; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpResponseException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients;public class HttpUtil {public static boolean returnResponseOfUrl(String url, OutputStream os){CloseableHttpClient httpclient = HttpClients.createDefault();HttpPost httpPost = new HttpPost(url);CloseableHttpResponse response = null;try{response = httpclient.execute(httpPost);StatusLine statusLine = response.getStatusLine();HttpEntity entity = response.getEntity();if(statusLine != null && statusLine.getStatusCode() >= 300){throw new HttpResponseException(statusLine.getStatusCode(),statusLine.getReasonPhrase());}if(entity == null){throw new ClientProtocolException("response contains no content");}entity.writeTo(os);return true;}catch(IOException e){e.printStackTrace();return false;}finally{if(response != null){try{response.close();}catch(IOException e){e.printStackTrace();}}}} }?
?中間代理servlet代碼如下:
@WebServlet("/HttpclientServlet") public class HttpclientServlet extends HttpServlet {private static final long serialVersionUID = 1L;public HttpclientServlet() {super();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String url = request.getParameter("url");if(url != null){if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){ // 如果出錯(cuò),再試一次// log.error("url:" + url);}; }}}}?html4項(xiàng)目中的訪問(wèn)頁(yè)面代碼如下:
<!doctype html> <html> <head><meta charset="utf-8"><meta name="keywords" content="jsonp"><meta name="description" content="jsonp"><title>jsonp</title><style type="text/css">*{margin:0;padding:0;}div{width:600px;height:100px;margin:20px auto;}</style> </head> <body><div><a href="javascript:;">jsonp測(cè)試</a></div><script type="text/javascript" src="js/jquery-1.11.1.js"></script> <script type="text/javascript"> $(function(){$("a").on("click", function(){ $.ajax({type:"post",url:"http://localhost:8888/html4/HttpclientServlet?url="+ecodeURIComponent("http://localhost:8080/html5/JsonServlet"),success:function(data) {console.log(data);console.log(data.name);console.log(data.age);var user = JSON.parse(data);console.log(user.name);console.log(user.age);}});}) }); </script> </body> </html>上面通過(guò):url=http://localhost:8080/html5/JsonServlet 將我們最終要跨域訪問(wèn)的url地址傳給自己服務(wù)器下的 HttpclientServlet. 然后在 HttpclientServlet 中使用httpclient訪問(wèn) 跨域 url? 中的servlet,成功之后,將返回的結(jié)果返回給客戶(hù)端。
html5項(xiàng)目中被 跨域 訪問(wèn)的servlet代碼如下:
@WebServlet("/JsonServlet") public class JsonServlet extends HttpServlet {private static final long serialVersionUID = 4335775212856826743L;protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {User user = new User();user.setName("yuanfang");user.setAge(100);Object obj = JSON.toJSON(user);System.out.println(user); // com.tz.servlet.User@164ff87System.out.println(obj); // {"age":100,"name":"yuanfang"} response.getWriter().println(obj);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);} }啟動(dòng)8888和8080端口的tomcat,訪問(wèn) http://localhost:8888/html4/jsonp.html ,結(jié)果如下:
我們注意到第二和第三項(xiàng)都打印的是 undefined ,這是因?yàn)?中間代理的 HttpclientServlet,使用的是直接輸出流的方式,所以最終返回的結(jié)果不是Json對(duì)象,而是字符串,所以需要使用 var user = JSON.parse(data); 來(lái)進(jìn)行解析成 javascript對(duì)象就可以,所以第四和第五項(xiàng)都正常輸出了結(jié)果。
如果想返回的是json對(duì)象,加一句代碼 response.setContentType("text/json;charset=utf-8"); 就可以:
if(url != null){response.setContentType("text/json;charset=utf-8");if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){ // 如果出錯(cuò),再試一次// log.error("url:" + url);}; } }這樣的話,瀏覽器在看到 contentType: "text/json;charset=utf-8" 時(shí),它的js執(zhí)行引擎會(huì)自動(dòng)幫助我們將字符串解析成json對(duì)象。也就是相當(dāng)于自動(dòng)調(diào)用了 JSON.parse(data) 的效果。
簡(jiǎn)單吧 ^__^
轉(zhuǎn)載于:https://www.cnblogs.com/digdeep/p/4198643.html
總結(jié)
以上是生活随笔為你收集整理的使用Httpclient来替代客户端的jsonp跨域解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 委托、Lambda表达式和事件
- 下一篇: [Everyday Mathematic