跨域(同源策略)

scr href 兩個能夠跨域的屬性html

 

<!-- 跨域獲取數據 -->
<!-- 同源策略:域名,協議,端口均相同
跨域:從一個域名的網頁去請求另外一個域名的資源,嚴格意義的定義是:只要域名,協議,端口有一個不一樣,就是跨域。
如何解決跨域:
1,跨域資源共享(CORS)
2,使用JSONP(經常使用,就是填充式JSON)
3,修改document.domain
4,使用window.name

下面是JSONP的介紹
1,什麼JSONP是JSON with Padding(填充式json)的簡寫,是應用JSON的一種新方法,也是一種跨域解決方案。
2,JSONP 由兩部分組成:回調函數 和 數據。
回調函數:當響應到來時應該在頁面中調用的函數
數據:是傳入回調函數中JSON數據
JSONP原理:
1,經過script標籤引入js文件
2,js文件加載成功後
3,執行咱們在url參數中指定的函數
直接使用XMLHttpRequest請求不一樣域上的數據時,是不能夠的,
可是,在頁面上引入不一樣域上的js腳本文件倒是能夠的。 -->

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>跨域</title>
</head>
<body>
<script>
//使用src屬性能夠跨域的特性,進行的一種跨域獲取數據的作法:
//1,封裝JSONP跨域函數,兩個參數:url,callback
// url:須要得到數據的不一樣域名,協議,端口號的地址
// callback:回調函數用於處理服務器返回的數據dat
//2,處理url,判斷是否有效,若有效,則給url添加一個自定義的函數,
// 用於接收服務器返回的數據data,
// 如:https://www.baidu.com?id=234&jsonp=getJSONP.abcd
// jsonp能夠隨便定義,只是過渡做用
// getJSONP.abcd :給getJSONP對象添加abcd屬性,該屬性是一個函數如:
// getJSONP.abcd=function(data){...},只要abcd是一個函數,
// 服務器就會自動把數據往abcd中塞,即function(data){...},
// data就是服務器返回的數據。
//3,最後建立script對象,併爲其設置src=url,便可。
//4,最後的最後,無論是否跨域成功,都要刪除已經建立的script對象,以及getJSONP中建立的方法,避免污染函數自己json

//這是老師寫代碼的思路,下面兩個是本身寫的代碼思路,最後一個比較適合本身。
//封裝JSONP跨域函數
function getJSONP(url,callback){
//判斷url是否爲false,若是爲false則直接返回,不執行
if (!url) {
return;
}
var arr=['a','b','c','d','e','f','g','j','h','i'];
//隨機生成4個0到9之間的索引,對應數組arr的下邊生成a到i之間的字母。組成一個函數名。
var r1=Math.floor(Math.random()*(9-0+1)+0);
var r2=Math.floor(Math.random()*(9-0+1)+0);
var r3=Math.floor(Math.random()*(9-0+1)+0);
var r4=Math.floor(Math.random()*(9-0+1)+0);api

//這裏的name,純粹是一個屬性,getJSON可自定義,與getJSON方法沒有關係
var name='getJSONP'+arr[r1]+arr[r2]+arr[r3]+arr[r4];跨域

//這裏的name是做爲getJSON方法對象的屬性,用於存放服務器返回的數據
var cbname='getJSONP.'+name;數組

//判斷url中地址是否含有"?"符號,jsonp做爲url發送數據的變量,能夠自定義
if (url.indexOf("?") === -1) {
url+="?jsonp="+cbname;
}else{
url+="&jsonp="+cbname;
}
//建立script標籤
var script=document.createElement('script');
//定義被腳本執行的回調函數
getJSONP[name]=function(data){
try{
// && 若是條件所有爲真,則返回最後一個
// && 若是有多爲false,則返回第一個false的條件。
//若是callback爲真,則執行callback(data)函數
callback && callback(data);
//捕獲異常,並無拋出
}catch(e){
///不執行
}finally{
//無論是否執行成功,都要進行刪除操做以下:
//最後刪除建立的函數getJSONP[name],以避免污染getJSONP函數自己
delete getJSONP[name];
//刪除script對象
script.parentNode.remove("script");
}
}
//給script設置src屬性,由於src是能夠跨域訪問不一樣域名,協議,端口的數據
script.src=url;
//把script添加到DOM中的head末尾。
document.getElementsByTagName("head")[0].appendChild(script);
}
getJSONP('http://class.imooc.com/api/jsonp',function(data){
for (var i = 0; i < data.length; i++) {
console.log(data[i].picUrl+"---"+data[i].linkUrl);
}
});服務器


/*//第一種本身的思路
/function getJSONP(url,callback){
//判斷url是否有效
if (!url) {
return;
}
//若是url是否有傳參數,而且給url傳一個接受數據的函數jsonp=getJSONP.abcd
if (url.indexOf("?")===-1) {
//這裏getJSONP.abcd爲了偷懶,沒有正式定義,正式應該使用隨機生成,以下面例子。
url+="?jsonp=getJSONP.abcd";
}else{
//這裏getJSONP.abcd爲了偷懶,沒有正式定義,正式應該使用隨機生成,以下面例子。
url+="&jsonp=getJSONP.abcd";
}app

//建立script對象
var script=document.createElement("script");
script.src=url;dom

//定義getJSONP.abcd函數,惟一的功能就是爲了接收服務器返回的函數data
//即:function(data){...裏面的代碼塊就是爲了處理data}
getJSONP[abcd]=function(data){
try{
callback && callback(data);
}catch(e){
//
}finally{
delete getJSONP.abcd;
script.parentNode.remove("script");
}
}
}
getJSONP("http://class.imooc.com/api/jsonp",function(data){
console.log(data);
});*/函數


//第二種本身的思路
//跨域,獲取不一樣域名,協議,端口的地址的數據,使用callback回調函數處理服務器返回的數據
/*function getJSONP(url,callback){
//判斷url是否有效
if (!url) {
return
}測試

//如下是隨機生成一個4位字母的name,其實也能夠隨便自定義個name,也能夠執行
var arr=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','h','o','p','q','r','s','z'];
var r1=Math.floor(Math.random()*arr.length),
r2=Math.floor(Math.random()*arr.length),
r3=Math.floor(Math.random()*arr.length),
r4=Math.floor(Math.random()*arr.length);
//這裏的name能夠隨便自定 如:var name=abdcdsdf;
//這裏只是爲了正式點才使用了隨機生成。
var name="getJSONP"+arr[r1]+arr[r2]+arr[r3]+arr[r4];
if (url.indexOf('?')===-1) {
//這裏等jsonp也能夠隨便定義,只是形式上過渡而已,如:
//假如:url="https://www.baidu.com?a=3&jsonp=getJSONPP.getJSONPabcd"
//重點是爲了給getJSONP對象添加一個getJSONPabcd函數用於接收服務器返回的data數據而已
url+="?jsonp=getJSONP."+name;
}else{
url+="&jsonp=getJSONP."+name;
}

//建立script對象,無論是否跨域成功都建立了script對象
var script=document.createElement("script");
//給script設置src屬性
script.src=url;
//把script對象添加到head末尾
document.getElementsByTagName("head")[0].appendChild(script);

//定義getJSONP[name]函數,用於接收數據 getJSONP[name]=function(data){ //判斷callback回調函數是不是有效的 //callback是用於處理服務器返回的數據 try{ callback&&callback(data); }catch(e){ //有異常不處理 }finally{ //無論跨域是否成功 //都要刪除已經建立的script對象,以及getJSONP.name的方法,避免污染getJSONP對象自己 delete getJSONP[name]; script.parentNode.remove(script);//必定要得到父元素後才能夠進行刪除指定對象 } } } //隨便給一個不一樣域名,不一樣協議,不一樣端口的地址進行測試 getJSONP('http://class.imooc.com/api/jsonp',function(data){ //無論得到什麼數據記得先查看其類型,再進行操做 console.log(typeof data); for (var i = 0; i < data.length; i++) { //能夠對該數據進行處理,如渲染到DOM樹上 //把數據渲染到DOM樹上有兩種方式: //1,使用document.createElement('a'); div.appendChild(建立的對象); //2,str="<a href='"+data[i].linkUrl+"'><img src='"+data[i].picUrl+"'/></a>" console.log(data[i]); } });*/ </script></body></html>

相關文章
相關標籤/搜索