JavaScript
跨域問題所困擾,其實有很多種解決方式,下面給大家介紹常用的幾種:1.jsonp解決跨域問題
客戶端程式碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jsonp-跨域</title>
<script type="text/javascript" src="resources/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
function callbackFn(data){
data = typeof data != 'string' ? JSON.stringify(data) : data;
console.log('callback:'+data);
}
function jsonpFn(){
$.ajax({
type:"get",
dataType:"jsonp",
url:"http://localhost:9393/ccy_server/server.jsp",
jsonpCallback:"callbackFn",
success:function(data){
data = typeof data != 'string' ? JSON.stringify(data) : data;
console.log('success.data:'+data);
}
});
}
function ajaxFn(){
var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
var url = "http://localhost:9393/ccy_server/server.jsp";
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState==4){
if(xmlhttp.status==200){
callbackFn(xmlhttp.responseText);
}
}
}
xmlhttp.open('GET',url,true);
xmlhttp.send(null);
}
ajaxFn();
//jsonpFn();
</script>
</head>
<body>
</body>
</html>複製程式碼
服務端程式碼:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String result = "{\"name\":\"ccy\",\"age\":18,\"info\":{\"address\":\"wuhan\",\"interest\":\"playCards\"}}";
out.println("callbackFn("+result+")");
%>複製程式碼
相信大家對此種方式並不陌生,需要引用jquery
庫檔案,並且要與服務端進行協調處理。
我先寫了個簡單的ajax
呼叫非同源的非同步請求直接報錯
執行jsonpFn
方法
成功獲取服務端資訊!
2.window.name解決跨域問題
在客戶端瀏覽器中每個頁面都有一個獨立的視窗物件window
,預設情況下window.name
為空,在視窗的生命週期中,載入的所有頁面共享一個window.name
並且每個頁面都有對此讀寫的許可權,window.name
會一直存在當前視窗,但儲存的字串不超過2M。
http://localhost:8383/ccy_client/window_name.html程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
<script type="text/javascript">
window.name = "我是 window.name 字串";
setTimeout(function(){
window.location = "http://localhost:9393/ccy_server/window_name.html";
},2000);
</script>
</head>
<body>
</body>
</html>複製程式碼
http://localhost:9393/ccy_server/window_name.html程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
<script type="text/javascript">
var str = window.name;
console.log('ccy_server.window_name:'+str);
</script>
</head>
<body>
</body>
</html>複製程式碼
chrome列印資訊
上面是以window.location
跳轉的方式獲取window.name
字串資訊,平時開發中經常需要非同步獲取,請繼續往下看:
http://localhost:8383/ccy_client/window_name_iframe.html程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
</head>
<body>
<script type="text/javascript">
var boo = false;
var iframe = document.createElement('iframe');
var loadData = function() {
if (boo) {
var data = iframe.contentWindow.name; //獲取window.name
console.log(data);
//銷燬資料
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
} else {
boo = true;
iframe.contentWindow.location = ""; // 設定的代理檔案,iframe重新載入
}
};
iframe.src = 'http://localhost:9393/ccy_server/window_name_iframe.html';
if (iframe.attachEvent) {
iframe.attachEvent('onload', loadData);
} else {
iframe.onload = loadData;
}
document.body.appendChild(iframe);
</script>
</body>
</html>複製程式碼
http://localhost:9393/ccy_server/window_name_iframe.html程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
<script type="text/javascript">
window.name = '我是 http://localhost:9393/ccy_server/window_name_iframe.html';
</script>
</head>
<body>
</body>
</html>複製程式碼
chrome列印資訊
成功獲取非同源地址的資料資訊,主要是通過iframe
的src
屬性,類似含有src
屬性的標籤都可以成功處理跨域問題img,script
3.postMessage解決跨域問題
h5
新特性,window.postMessage(msg,targetOrigin)
;
msg
:傳入的字串資訊
targetOrigin
:目標源(協議主機埠有效)
同樣藉助iframe
進行跨域操作
http://localhost:8383/ccy_client/postMessage.html程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>postMessage-跨域</title>
</head>
<body>
<iframe id="ifr" src="http://localhost:9393/ccy_server/postMessage.html" style="display: none;"></iframe>
<br>
<input id="txt" type="text" style="width:600px;height:70px;"/>
<br>
<input id="btn" type="button" value="獲取9393資料" onclick="getData();" style="width:180px;height:60px;"/>
<script type="text/javascript">
var data;
function handleMsg(e){
e = e || event;
data = e.data;
console.log('8383:'+e.data);
}
if(window.addEventListener){
window.addEventListener('message', handleMsg);
}else{
window.attachEvent('onmessage', handleMsg);
}
function getData(){
document.getElementById('txt').value=data;
var msg = 'http://localhost:8383/ccy_client/postMessage.html';
window.frames[0].postMessage(msg, 'http://localhost:9393');
}
</script>
</body>
</html>複製程式碼
http://localhost:9393/ccy_server/postMessage.html程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>postMessage-跨域</title>
</head>
<body>
<script type="text/javascript">
function handleMsg(e){
e = e || event;
console.log('9393:'+e.data);
}
if(window.addEventListener){
window.addEventListener('message', handleMsg);
}else{
window.attachEvent('onmessage', handleMsg);
}
window.onload = function(){
var msg = '我是 http://localhost:9393/ccy_server/postMessage.html';
window.parent.postMessage(msg, 'http://localhost:8383');
}
</script>
</body>
</html>複製程式碼
chrome列印資訊
成功獲取非同源資料,將非同源地址嵌入獲取資料頁面視窗。
4.Java解決跨域問題
通過客戶端頁面的ajax
非同步請求同源頁面,再通過Java
的HttpURLConnect
或者HttpClient
進行轉換即可,此處就不再贅述。
還有一種就是設定服務端的Header
,公司產品ggly
的api
就是這麼處理的。
5.參考資料
《JavaScript權威指南》