JAVA調用https, JS跨域請求,客戶端解決JS跨域問題, SOP

同源協議 (SOP,Same-Origin-Policy) 可防止從一個來源加載的腳本獲取或操縱來自另一來源的文檔的屬性或方法。術語來源 是域名、應用程序協議和運行腳本文檔的端口的結合。可能存在關于 SOP 概念的一些誤解;SOP 指只能從站點 A、不能從站點 B 獲取信息。您需要知道在 SOP 限制下可以做什么,不可以做什么。

1.JAVA https請求

在做微信服務號的時候出現的問題,解決方法:自定義證書管理器。證書管理器的作用就是讓它信任我們指定的證書,意味著信任所有證書,不管是否權威機構頒發,證書有了,通用的https請求方法就不難實現了。

package com.qq.weixin.util;  
import java.io.BufferedReader;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.io.OutputStream;  
import java.net.URL;  
import java.security.cert.CertificateException;  
import java.security.cert.X509Certificate;  
  
import javax.net.ssl.HttpsURLConnection;  
import javax.net.ssl.SSLContext;  
import javax.net.ssl.SSLSocketFactory;  
import javax.net.ssl.TrustManager;  
import javax.net.ssl.X509TrustManager;  
    
/**  
 * 公眾平臺通用接口工具類  
 *  from==> 
 *      shttp://blog.csdn.net/lyq8479/article/details/9841371 
 * @author liuyq  
 * @date 2013-08-09  
 */    
public class WXHttpUtil {    
      
    /**  
     * 發起https請求并獲取結果  
     *   
     * @param requestUrl 請求地址  
     * @param requestMethod 請求方式(GET、POST)  
     * @param outputStr 提交的數據  
     * @return String  
     */    
    public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) throws Exception {    
        StringBuffer buffer = new StringBuffer();    
        // 創建SSLContext對象,并使用我們指定的信任管理器初始化    
        TrustManager[] tm = { new MyX509TrustManager() };    
        SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");    
        sslContext.init(null, tm, new java.security.SecureRandom());    
        // 從上述SSLContext對象中得到SSLSocketFactory對象    
        SSLSocketFactory ssf = sslContext.getSocketFactory();    
          
        URL url = new URL(requestUrl);    
        HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();    
        httpUrlConn.setSSLSocketFactory(ssf);    
          
        httpUrlConn.setDoOutput(true);    
        httpUrlConn.setDoInput(true);    
        httpUrlConn.setUseCaches(false);    
        // 設置請求方式(GET/POST)    
        httpUrlConn.setRequestMethod(requestMethod);    
          
        if ("GET".equalsIgnoreCase(requestMethod))    
            httpUrlConn.connect();    
          
        // 當有數據需要提交時    
        if (null != outputStr) {  
            OutputStream outputStream = httpUrlConn.getOutputStream();    
            // 注意編碼格式,防止中文亂碼    
            outputStream.write(outputStr.getBytes("UTF-8"));    
            outputStream.close();    
        }    
          
        // 將返回的輸入流轉換成字符串    
        InputStream inputStream = httpUrlConn.getInputStream();    
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");    
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);    
          
        String str = null;    
        while ((str = bufferedReader.readLine()) != null) {    
            buffer.append(str);    
        }    
        bufferedReader.close();    
        inputStreamReader.close();    
        // 釋放資源    
        inputStream.close();    
        inputStream = null;    
        httpUrlConn.disconnect();   
        String result = buffer.toString();  
        System.out.println("請求結果==>" + result);  
        return result;    
    }    
      
    /**  
     * 證書信任管理器(用于https請求)  
     *   
     * @author liufeng  
     * @date 2013-08-08  
     */    
    public static class MyX509TrustManager implements X509TrustManager {    
        
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {    
        }    
        
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {    
        }    
        
        public X509Certificate[] getAcceptedIssuers() {    
            return null;    
        }    
    }  
}

2. JS跨域請求

在網上看了好多方法:

  • 1)iframe
  • 2)document.domain
  • 3)window.name
  • 4)script
  • 5)XDomainRequest (IE8+)
  • 6)XMLHTTPRequest (Firefox3.5+)
  • 7)postMessage (HTML5)
  • 8)后臺代理

本文此處講解一下JsonP的處理注意事項

JSONP的實現思路很簡單

  • 1)前端創建script標記,設置src,添加到head中(你可以往body中添加);
  • 2)后臺返回一個js變量jsonp,這個jsonp就是請求后的JSON數據;
  • 3)回調完成后刪除script標記(還有一些清理工作如避免部分瀏覽器內存泄露等)。

客戶端直接使用JsonP請求:

$.ajax({    
        url:"http://crossdomain.com/services.php",    
        dataType:'jsonp',    
        data:'',    
        jsonp:'callback',    
        success:function(result) {    
            for(var i in result) {    
                alert(i+":"+result[i]);//循環輸出a:1,b:2,etc.    
            }    
        },    
        timeout:3000    
    }); 

服務器端處理:(Play Framework寫的服務器)

String callback = request.params.get("callback");  
String result = callback + "(" + JSON.toJSONString(dataMap) + ")";  
renderText(result); 

返回時數據用callback+()包上。

3. 利用客戶端解決方案改進跨域通信

http://www.ibm.com/developerworks/cn/web/wa-crossdomaincomm/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容