JavaScript之跨域解決方式
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.參考資料
ofollow,noindex">www.sojson.com/blog/121.ht…
《JavaScript權威指南》