跨域訪問與同源策略

 

由於在同一個瀏覽器窗口中可以同時打開多個網站的頁面,並且它們都處於同一個會話中,若是不由止跨域訪問則會形成用戶隱私數據泄露和登陸身份冒用的問題,因此瀏覽器會使用同源策略限制跨域訪問。jquery

在瀏覽器中,經過JS代碼訪問不一樣域名下的URL(JS的XHR/AJAX)或者iframe(JS訪問iframe內部的DOM)時,會被禁止訪問。而不是經過JS代碼進行的跨域訪問不存在跨域問題!好比能夠跨域加載圖片、引用JS文件、下載各類文件、使用iframe跨域嵌入其它網站的頁面都是容許的。api

跨域訪問被禁止有時會給應用開發帶來阻礙,但在符合特定條件時也有相應的方法在保證安全的狀況下可以解決跨域訪問的問題。跨域

  1. 在對方的服務器中的響應頭中添加 Access-Control-Allow-Origin 容許哪些域進行跨域訪問它是值能夠是 域名,或者 * 。這種方案只有在對方信任或不在意(安全)的狀況下才能使用。
  2. 若是域名都是同一個根域名的子域名,則能夠使用document.domain = "根域名" 來統一JS執行環境中的域名。這種方案只能在同一個公司或組織的內部使用。
  3. JSONP    JSON Padding,原理是:瀏覽器不限制經過script標籤引入其它網站的腳本,因此能夠經過JS向頁面上動態添加一個script標籤而且指定其 src 爲一個特殊的url,對方的服務器針對這個url的請求,會進行特殊處理,如:

head標籤中動態添加如下script標籤瀏覽器

<script src="http://api.baidu.com/weather/zhengzhou/functionName"></script>安全

會致使瀏覽器向上述URL發起一個GET請求(JSONP只能是GET請求)服務器

 

對方的服務器收到這個請求後,會返回一個特殊的JS文件:dom

 

functionName && functionName({函數

    天氣數據網站

})url

 

若是此時在頁面中定義了functionName函數,則functionName函數會被調用,而且可以獲得天氣數據!

這種將JSON數據放入指定函數參數位置的跨域訪問解決方案被稱爲JSONP。即便用JSON填充函數後面的()內部的空白(padding)

這種方案能夠跨域任意域名,可是必是對方有意這樣設計才能使用。若是對方不支持將JSON數據padding到函數名後面的()中,則JSONP沒法使用。

jQuery中 $.getJSON() 這個方法支持 JSONP !!!

url後面加 callback=? 便可jQuery會自動生成函數名並將調用轉交給getJSON中的回調函數。

  1. 將要請求的URL發送給本身的服務端,讓服務端發起請求(服務端沒有跨域限制),服務端請求成功後,將數據再回傳給瀏覽中的JS----服務端代理請求。

這種方式只要本身的服務端支持一下就能夠了,是比較經常使用的方案,沒有任何限制,並且這種方安還能夠實現其它方案沒法實現的功能:

經過服務端抓取別人的網頁,將網頁上的數據提取出來,變成JSON返回

在Node.js中,使用cheerio模塊能夠像使用jquery同樣從HTML字符串中篩選並提取想要的數據。

  1. 使用任何能夠利用的瀏覽器端中間機制實現跨域交換數據,如:

window.name在代碼中使用name變量時實際上使用的是window對象的name屬性,可是name屬性是window對象的內部屬性。它只接受字符串值,若是給它賦其它值,將會直接被轉換成字符串!!!!尤爲是賦一個對象給name變量的時候,會致使數據丟失!!!(對象toString()後是[object Object])。可是name有一特別性質能夠被用來作跨域數據交換name值不會隨全局做用域被銷燬,無論窗口跳轉到哪一個頁面,無論窗口打開了多少個頁面,name的值都是通用的。其它的,諸如 location.hash 也能夠用來作跨域數據交換(主要是iframe)

相關文章
相關標籤/搜索