1.爲何會出現跨域問題php
web瀏覽器中包含JavaScript解釋器,也就是說,一旦載入Web頁面,就能夠任意的JavaScript代碼在計算機裏執行。安全隱患也就隨之而來,因此由Netscape提出了一個著名的安全策略——同源策略,即JavaScript腳本不能讀取從不一樣服務器載入的文檔的內容。 html
2.同源策略的具體狀況web
一個完整的url地址包括:ajax
協議名://域名:端口號/資源路徑json
URLapi |
說明跨域 |
是否容許通訊瀏覽器 |
http://www.a.com/index.html安全 ftp://www.a.com/detail.html服務器 |
協議名不一樣 |
不容許 |
http://www.a.com/index.html http://www.b.com/detail.html |
協議名相同,域名不一樣 |
不容許 |
http://www.a.com:8000/index.html http://www.a.com:3000/detail.html |
協議名和域名都相同,端口號不一樣 |
不容許 |
http://www.a.com/index.html http://70.80.90.00 /detail.html |
協議名相同,假設ip地址表示的是同一個網址 |
不容許 |
http://www.a.com/index.html http://www.a.com/detail.html |
協議名相同,域名相同,端口號相同 |
容許 |
總結:若是協議名、主機名或者端口號不一樣,就是跨域,即便是ip地址和主機名錶明同一個網址。
3.跨域問題的幾種解決方案
(1).動態建立script
由於script不受同源策略的影響,因此用js動態的加載url,達到跨域。
function loadScript(url, func) { var head = document.head || document.getElementByTagName('head')[0]; var script = document.createElement('script'); script.src = url; script.onload = script.onreadystatechange = function(){ if(!this.readyState || this.readyState=='loaded' || this.readyState=='complete'){ func(); script.onload = script.onreadystatechange = null; } }; head.insertBefore(script, 0); } window.baidu = { sug: function(data){ console.log(data); } } loadScript('http://suggestion.baidu.com/su?wd=w',function(){console.log('loaded')});
(2).jsonp
JSON是一種基於文本的數據交換方式,以鍵值對的形式存儲數據,輕量級數據格式,適用互聯網傳遞。而JSONP是一種非正式的傳輸協議,該協議的原理是:web客戶端經過與調用腳本如出一轍的方式,來調用跨域服務器上動態生成js格式文件(JSON後綴,封裝客戶端須要的數據),用戶傳遞一個callback參數給服務端,而後服務端返回數據時會將這個callback函數做爲函數名來包裹住JSON數據,這樣客戶端就可使用JSON數據進行數據處理了。
//jQuery實現jsonp跨域的方法: //$.JSON方法: $.getJSON({‘myUrl?callback=?’,function(data){ //處理data數據 }); //$.ajax方法: $.ajax({ type:」get」, url:」http://www.baidu.com/..」, datatype:」jsonp」, jsonp:」callback」,//用於得到jsonp回調函數名的參數名,通常默認爲callback jsonpCallback:」func()」,//自定義的jsonp回調函數名稱 success:function(json){ console.log(json); }, error:function(err){ console.log(err); } });
(3).postMessage
在 HTML5 中, window 對象增長了一個很是有用的方法:
otherWindow.postMessage(message, targetOrigin);
otherWindow:調用的window;message:發送的消息或對象;targetOrigin:目標的源,* 表示任意。
window.addEventListener("message", receiveMessage, false); function receiveMessage(event) { var origin = event.origin || event.originalEvent.origin; // For Chrome, the origin property is in the event.originalEvent object. if (origin !== "http://example.org:8080") return;
event.source.postMessage("the data is",event.origin);
}
(4)、使用CORS跨域
CORS(跨來源資源共享)是一份瀏覽器技術的規範,提供了web服務器從不一樣網域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是JSONP模式的現代版。
①. 客戶端 使用絕對地址
xhr.open("GET", "http://blog.csdn.net/api", true);
②. 服務器
服務器端對於CORS的支持,主要就是經過設置Access-Control-Allow-Origin來進行的。若是瀏覽器檢測到相應的設置,就能夠容許Ajax進行跨域的訪問。
在PHP中:只須要使用以下的代碼設置便可。
<?php
header("Access-Control-Allow-Origin:*");
以上的配置的含義是容許任何域發起的請求均可以獲取當前服務器的數據。這樣全部域的請求都被容許會形成潛在的不安全性。因此咱們應該儘可能有針對性的對限制安全的來源,好比限制只能從博客園上請求
Access-Control-Allow-Origin: http://www.cnblogs.com
(5).web socket(ws協議)
var socket = new WebSockt('ws://www.baidu.com');//http->ws; https->wss
socket.send('hello WebSockt');
socket.onmessage = function(event){
var data = event.data;
}