跨域訪問請求處理
在瀏覽器中,通過js程式碼訪問不同域名下的url,可以是js的xhr請求,或者是ajax請求,或者是iframe(js訪問iframe內部的DOM時)。這時,會被禁止訪問。出現這種問題時,需要通過跨域訪問。
不是通過js程式碼進行的跨域訪問,不存在跨域(禁止訪問)問題
跨域問題的解決方案有很多
一,在對方伺服器的響應頭中新增 Access-Control-Allow-Origin。
它的值可以是域名,也可以是*。
這種方案,只有在對方信任或者不在乎伺服器安全的情況下,才能使用。
二,如果域名都是用一個域名的子域名。則可以使用document.domin = “根域名”來統一執行環境中的域名。
這種方案只能在同一個公司或者同一個組織內部使用
如:
document.domain = "jundong.com"
var data = $('iframe')[0].contentWindow.document.body.innerText;
console.log(data)
但iframe引入的檔案裡,js也需要指明一樣的子域名:
document.domain = "jundong.com"
三,JSONP (JSON Padding)
jsonp處理跨域請求是最常用的一種辦法。
原理:瀏覽器不限制通過script標籤引入其他網站的指令碼,所以通過javaScript向頁面動態的新增一個script標籤。並且指定其url為一個特殊的url,對方的伺服器針對這個特殊的url的請求,進行特殊的處理。
例如:向body裡新增一個script標籤
<script src="http://api/baidu.com/weather/functionName"></script>
會讓瀏覽器向src裡的url發起一個get請求。因為jsonp只能是get請求。
對方的伺服器在收到這個請求後,會返回一個特殊的js檔案,檔案的內容如下:
functionName({
天氣資料
})
如果此時在頁面中定義了functionName函式,則functionName會被呼叫,並且能夠獲得天氣資料。
這種將json資料放入指定的函式引數位置的跨域訪問解決方案被稱為JSONP。
function functionName(data){
console .log(data)
}
var s = document.createElement('script')
s.src = "http://api.map.baidu.com/telematics/v3/weather?location=北京&output=json&ak=iw5m2G7ayDow8ofDdDGVUMB3&mcode=com.BaiduWeather&callback=functionName";
document.body.appendChild(s)
在jQuery當中,$.getJSON()方法支援JSONP,在url新增callback=?即可
$.getJSON("http://api.map.baidu.com/weather?location="北京"&callback=?",null,function(res){
console.log(res)
})
四,將要請求的url傳送給自己的服務端,讓服務端發起請求(服務端沒有跨域限制)
服務端請求成功後,再回傳給瀏覽器中的js。這種方法稱為服務端代理請求,這種方式只需要自己的服務端支援一下就可以,是比較常用的方法,沒有任何限制。
這種方式還能實現其他方案無法實現的功能。通過服務端抓取別人的網頁,將網頁上的資料取出來,變成json返回給我們。
過程:瀏覽器–>伺服器–>第三方網頁–>抓取資料–>轉成json返回給瀏覽器
實際應用:在nodejs中,使用cheerio模組,可以像jquery一樣從HTML字串中篩選並提取想要的字元。