跨域問題解決方式(HttpClient安全跨域 & jsonp跨域)

來源:互聯網
上載者:User

標籤:不能   final   包括   交換   ack   code   txt   pcl   open   

 

1 錯誤情境                                         

       今天要把項目部署到外網的時候,出現了這種問題, 我把兩個項目放到自己原生tomcat下, 進行代碼調試, 執行

都沒有問題的, 一旦把我須要調用介面的項目B放到其它的server上, 就會報錯, 無法通過Ajax調用springMVC的介面,

這是什麼原因呢?

      當我使用json ajax post請求傳遞資料的時候在web端出錯:XMLHttpRequest cannot loadhttp://ip:8082/security/auth/outside.do. Origin http://ip:8080 is not allowed by Access-Control-Allow-Origin.

 

2 初識jsonp                               

      經過在網上尋找, 網上大多數說是跨域問題. 解決跨域問題據說是jsonp, 百度了一篇文章, 無論三七二十一就一下

子把ajax傳遞的資料類型dataType 改成為jsonp, 並使用get方式, 單純的覺得, json和jsonp沒啥差別, 執行, 報錯, 如

所看到的:

 

      沒有了上述的 is not allowed ....的錯誤, 變成了僅僅剩下500的錯誤, 說明jsonp起了些作用, 我的bug的問題就是在於網上說的"跨域" 。

而到底什麼是跨域呢?

 

3 什麼是跨域?什麼是不跨域?           

      上沒有過多的去測試,一句話:同一個ip、同一個網路通訊協定、同一個port。三者都滿足就是同一個域,否則就是

跨域問題了。

而為什麼開發人員最初不直接定為一切可跨域的呢?預設的為什麼都是不可跨域呢?這就涉及到了同源策

略,為了系統的安全,由Netscape提出一個著名的安全性原則。

如今全部支援JavaScript的瀏覽器都會使用這個策略。

所謂同源是,網域名稱。協議,port同樣。當我們在瀏覽器中開啟百度和Google兩個網站時,百度瀏覽器在運行一個指令碼的

時候會檢查這個指令碼屬於哪個頁面的。即檢查是否同源,僅僅有和百度同源的指令碼才會被運行,假設沒有同源策略,那

隨便的向百度中注入一個js指令碼,彈個惡意廣告,通過js竊取資訊。這就非常不安全了。

 

4 跨域問題怎樣解決?jsonp為什麼能解決跨域問題?和json有什麼差別?

      關於解決跨域問題,有多種解決方式,解決方式例如以下。

 

      4.1 方案一

      ajax請求地址改為自己系統的後台地址,之後在自己的後台用HttpClient請求url。封裝好的跨域請求url工具類

代碼例如以下所看到的。

 

<span style="font-size:18px;">@SuppressWarnings("all")public final class UrlUtil {private static HttpClient httpClient = new HttpClient();/** * @Title: getDataFromURL * @Description: 依據URL跨域擷取輸出結果。支援http * @param strURL *            要訪問的URL地址 * @param param *            參數 * @return 結果字串 * @throws Exception */public static String getDataFromURL(String strURL, Map<String, String> param) throws Exception {URL url = new URL(strURL);URLConnection conn = url.openConnection();conn.setDoOutput(true);OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());final StringBuilder sb = new StringBuilder(param.size() << 4); // 4次方final Set<String> keys = param.keySet();for (final String key : keys) {final String value = param.get(key);sb.append(key); // 不能包括特殊字元sb.append(‘=‘);sb.append(value);sb.append(‘&‘);}// 將最後的 ‘&‘ 去掉sb.deleteCharAt(sb.length() - 1);writer.write(sb.toString());writer.flush();writer.close();InputStreamReader reder = new InputStreamReader(conn.getInputStream(), "utf-8");BufferedReader breader = new BufferedReader(reder);// BufferedWriter w = new BufferedWriter(new FileWriter("d:/1.txt"));String content = null;String result = null;while ((content = breader.readLine()) != null) {result += content;}return result;}/** * @Title: postMethod * @Description: 依據URL跨域擷取輸出結果。支援https * @param url *            要訪問的URL地址(http://www.xxx.com?) * @param urlParm *            參數(id=1212&pwd=2332) * @return 結果字串 */public static String postMethod(String url, String urlParm) {if (null == url || "".equals(url)) {// url = "http://www.baidu.com";return null;}PostMethod post = new PostMethod(url); // new UTF8PostMethod(url);if (null != urlParm && !"".equals(urlParm)) {String[] arr = urlParm.split("&");NameValuePair[] data = new NameValuePair[arr.length];for (int i = 0; i < arr.length; i++) {String name = arr[i].substring(0, arr[i].lastIndexOf("="));String value = arr[i].substring(arr[i].lastIndexOf("=") + 1);data[i] = new NameValuePair(name, value);}post.setRequestBody(data);}int statusCode = 0;String pageContent = "";try {statusCode = httpClient.executeMethod(post);if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {pageContent = post.getResponseBodyAsString();return pageContent;}} catch (Exception e) {e.printStackTrace();return null;} finally {post.releaseConnection();}return null;}public static String doPost(String url, String json) throws Exception {PostMethod postMethod = new PostMethod(url);StringRequestEntity requestEntity = new StringRequestEntity(json, "application/json", "UTF-8");postMethod.setRequestEntity(requestEntity);/* 發送請求,並擷取響應對象 */int statusCode = httpClient.executeMethod(postMethod);String result = null;if (statusCode == HttpStatus.SC_OK) {result = postMethod.getResponseBodyAsString();} else {System.out.println("Method failed: " + postMethod.getStatusLine());}return result;}public static String post(String url, Map<String, String> params) {DefaultHttpClient httpclient = new DefaultHttpClient();String body = null;HttpPost post = postForm(url, params);body = invoke(httpclient, post);httpclient.getConnectionManager().shutdown();return body;}private static HttpPost postForm(String url, Map<String, String> params) {HttpPost httpost = new HttpPost(url);List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();Set<String> keySet = params.keySet();for (String key : keySet) {BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, params.get(key));nvps.add(basicNameValuePair);}try {httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));} catch (UnsupportedEncodingException e) {e.printStackTrace();}return httpost;}private static String invoke(DefaultHttpClient httpclient, HttpUriRequest httpost) {HttpResponse response = sendRequest(httpclient, httpost);String body = paseResponse(response);return body;}private static HttpResponse sendRequest(DefaultHttpClient httpclient, HttpUriRequest httpost) {HttpResponse response = null;try {response = httpclient.execute(httpost);} catch (Exception e) {e.printStackTrace();}return response;}private static String paseResponse(HttpResponse response) {HttpEntity entity = response.getEntity();String body = null;try {body = EntityUtils.toString(entity);} catch (Exception e) {e.printStackTrace();}return body;}public static void main(String[] args) throws Exception {String url = "http://ip:8082/security/auth/outside.do";Map<String, String> map = new HashMap<String, String>();map.put("loginName", "root");map.put("code", "vms2.0");String msg = post(url, map);JSONArray jary = JsonUtil.Json2JSONArray(msg);for (int i = 0; i < jary.length(); i++) {JSONObject obj = jary.getJSONObject(i);System.out.println(obj);//System.out.print(obj.getString("classid"));//System.out.print("\t"+obj.getString("classname"));//System.out.println("\t"+obj.getString("sonclass"));}//System.out.println(jary);}}</span>


       當然要匯入httpclient-4.3.1.jar包到自己的項目中哦。這樣把請求的參數內容放到map中。通過HttpClent來實現跨域請求。

       4.2 解決方式二

       兩個系統之間的資料傳遞是通過ajax post請求,傳遞json的方式來完畢,我們在這裡能夠使用jsonp的方式。但

是json和jsonp截然不同。首先說說神馬是json,再說神馬是jsonp。

json

       全拼(javaScript Object Notation)輕量級的資料交換格式,易於機器解析和產生。基於javaScript

Programming Language,StandardECMA Edition December1999的一個子集。json全然獨立於語言的文本格

式,可是也使用類似於C語言家族的習慣(include c c++ c# java javaScript perl python)等。這些特性使得json

成為理想的資料交換語言。格式為key,value格式,詳細就不贅述了。

jsonp

       jsonp全拼是(json with Padding)是json的一種使用模式,padding意思為填料,墊料,填充,填補。json可

以說是名詞,而jsonp是動賓短語,兩者有聯絡,可是有本質的差別,就像米飯和把米飯填充到碗裡一樣,那米飯和

米飯填是一樣的麼,我們自然明了了。

 

      jsonp算是鑽空子實現的跨域,究竟通過jsonp詳細怎樣解決跨域問題呢?本篇過長了,我們下篇分曉。goodnight...

 

 

 

跨域問題解決方式(HttpClient安全跨域 &amp; jsonp跨域)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.