JavaScript出於安全方面的考慮,不容許跨域調用其餘頁面的對象。但在安全限制的同時也給注入iframe或是ajax應用上帶來了很多麻煩。這裏把涉及到跨域的一些問題簡單地整理一下。php
首先什麼是跨域,簡單地理解就是由於JavaScript同源策略的限制,a.com 域名下的js沒法操做b.com或是c.a.com域名下的對象。更詳細的說明能夠看下錶: ajax
1 | http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 容許 |
2 | http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不一樣文件夾 | 容許 |
3 | http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不一樣端口 | 不容許 |
4 | http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不一樣協議 | 不容許 |
5 | http://www.a.com/a.js http://70.32.92.74/b.js |
域名和域名對應ip | 不容許 |
6 | http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不一樣 | 不容許 |
7 | http://www.a.com/a.js http://a.com/b.js |
同一域名,不一樣二級域名(同上) | 不容許(cookie這種狀況下也不容許訪問) |
8 | http://www.cnblogs.com/a.js http://www.a.com/b.js |
不一樣域名 | 不容許 |
注意兩點:json
第一:若是是協議和端口形成的跨域問題「前臺」是無能爲力的;跨域
第二:在跨域問題上,域僅僅是經過「URL的首部」來識別而不會去嘗試判斷相同的ip地址對應着兩個域或兩個域是否在同一個ip上。 「URL的首部」指window.location.protocol +window.location.host,也能夠理解爲「Domains, protocols and ports must match」。瀏覽器
雖然瀏覽器默認禁止了跨域訪問,但並不由止在頁面中引用其餘域的JS文件,並能夠自由執行引入的JS文件中的function(包括操做cookie、Dom等等)。根據這一點,能夠方便地經過建立script節點的方法來實現徹底跨域的通訊。具體的作法能夠參考YUI的Get Utility安全
這裏判斷script節點加載完畢仍是蠻有意思的:ie只能經過script的readystatechange屬性,其它瀏覽器是script的load事件。如下是部分判斷script加載完畢的方法。cookie
封裝後的jsonpapp
1 document.onclick = function(){ 2 var url = "http://localhost/jsonp/data/jsonp3.php"; 3 jsonp(url,function(res){ 4 alert(res) 5 },{ 6 user:"admin", 7 pass:123, 8 // 根據後臺指定的字段名,傳入回調函數名,傳給後臺
9 zxc:"ewqrwer213213213", 10 // 用來保存後臺接收的 回調函數名所在的字段名,傳給本身的函數
11 columnName:"zxc"
12 }) 13 } 14
15 function jsonp(url,callback,data){ 16 // 解析要發送的數據
17 data = data || {}; 18 var str = ""; 19 for(var i in data){ 20 str += `${i}=${data[i]}&`; 21 } 22 // 將數據拼接到url
23 url = url + "?" + str.slice(0,str.length-1); 24
25 // jsonp的功能:1.建立script
26 var script = document.createElement("script"); 27 script.src = url; 28 document.body.appendChild(script); 29
30 // jsonp的功能:2.建立準備被資源執行的全局函數
31 window[data[data.columnName]] = function(res){ 32 callback(res); 33 } 34 }