JavaScript
跨域問題所困擾,其實有不少種解決方式,下面給你們介紹經常使用的幾種:
客戶端代碼:
javascript
<!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>複製代碼
服務端代碼:
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
庫文件,而且要與服務端進行協調處理。java
我先寫了個簡單的ajax
調用非同源的異步請求直接報錯jquery
執行jsonpFn
方法
ajax
成功獲取服務端信息!chrome
在客戶端瀏覽器中每一個頁面都有一個獨立的窗口對象window
,默認狀況下window.name
爲空,在窗口的生命週期中,載入的全部頁面共享一個window.name
而且每一個頁面都有對此讀寫的權限,window.name
會一直存在當前窗口,但存儲的字符串不超過2M。json
http://localhost:8383/ccy_client/window_name.html代碼api
<!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
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打印信息
成功獲取非同源數據,將非同源地址嵌入獲取數據頁面窗口。
經過客戶端頁面的ajax
異步請求同源頁面,再經過Java
的HttpURLConnect
或者HttpClient
進行轉換便可,此處就再也不贅述。
還有一種就是設置服務端的Header
,公司產品ggly
的api
就是這麼處理的。
《JavaScript權威指南》