国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解Javascript幾種跨域方式總結

2019-11-19 17:24:58
字體:
來源:轉載
供稿:網友

在客戶端編程語言中如javascript,同源策略規定跨域之間的腳本是隔離的,一個域的腳本不能訪問和操作另外一個域的絕大部分屬性和方法。只有當兩個域具有相同的協議,相同的主機,相同的端口時,我們就認定他們是相同的域。可是在實際開發中我們經常需要獲取其他域的資源,這個時候各種不同的跨域資源方式就各顯神通了,今天主要來總結一下工作中常用的幾種跨域方式,以備查詢。

1.window.name

window 對象的name屬性是一個很特別的屬性,當在 frame 中加載新頁面時,name 的屬性值依舊保持不變。那么我們可以在頁面 A中用iframe加載其他域的頁面B,而頁面B中用JavaScript把需要傳遞的數據賦值給window.name,iframe加載完成之后,此時 name 屬性值可被獲取到,以訪問 Web 服務發送的信息。但 name 屬性僅對相同域名的 frame 可訪問。這意味著為了訪問 name 屬性,當遠程 Web 服務頁面被加載后,必須導航 frame 回到原始域。即頁面A修改iframe的地址,將其變成同域的一個地址,然后就可以讀出window.name的值了。一旦 name 屬性獲得,銷毀 frame 。這個方式非常適合單向的數據請求,而且協議簡單、安全。

頁面B(www.jesse.com/data.html)代碼如下:

<script type="text/javascript">window.name = 'I was there!';// 這里是要傳輸的數據,大小一般為2M,IE和firefox下可以大至32M左右// 數據格式可以自定義,如json、字符串</script>

頁面A(www.jack.com/index.html)代碼如下:

<script type="text/javascript">var state = 0,  iframe = document.createElement('iframe'),  loadfn = function() {    if (state === 1) {      var data = iframe.contentWindow.name; // 讀取數據      console.log(data); //彈出'I wasthere!'      (function(){        //獲取數據以后銷毀這個iframe。        iframe.contentWindow.document.write('');        iframe.contentWindow.close();        document.body.removeChild(iframe);      })();    } else if (state === 0) {      state = 1;      // 設置的代理頁面使其回原始域      iframe.contentWindow.location = "http://www.jack.com/proxy.html";     }  };iframe.src = 'http://www.jesse.com/data.html';if (iframe.attachEvent) {  iframe.attachEvent('onload', loadfn);} else {  iframe.onload = loadfn;}document.body.appendChild(iframe);</script>

2.具備src的標簽

雖然瀏覽器默認禁止了跨域訪問,但并不禁止在頁面中用標簽的src屬性引用其他域的文件。根據這一點,可以方便地通過創建具有src屬性的節點方法來實現完全跨域的通信。使用這種原理的跨域方式有以下幾種:

動態創建script

例如我要從域A的頁面pageA加載域B的數據,那么在域B的頁面pageB中我以JavaScript的形式聲明pageA需要的數據,然后在 pageA中用script標簽把pageB加載進來,那么pageB中的腳本就會得以執行。

pageA(www.jack.com/index.html)代碼如下:

function getData(data){  //這里是對獲取的數據的相關操作  console.log(data);  //數據獲取到后移除創建的script標簽  document.body.removeChild(originData);}var originData = document.createElement('script');originData.src = 'http://www.jesse.com/data.js';originData.setAttribute("type", "text/javascript");document.body.appendChild(originData);

pageB(www.jesse.com/data.js)代碼如下:

getData('這里是遠程跨域獲取的數據');//數據格式可以自定義,如json、字符串

jsonp

在用$.ajax()獲取遠程數據時,如果是跨域資源則可以使用jsonp方法,以前一直以為jsonp是ajax的一種,后來才明白他們根本就不是一回事。ajax是以xhr方式請求數據的,而jsonp是以script方式請求數據的,這個就是和上面的動態創建script方式一樣。

pageA(www.jack.com/index.html)代碼如下:

$.ajax({  //JSONP不支持POST方式  type:"GET",  url:"http://www.jesse.com/data.php",  dataType:"jsonp",  //自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名,也可以寫"?",jQuery會自動為你處理數據  jsonpCallback:"getData",  success: function(data){    console.log(data);  },  error: function(){    console.log('fail');  }})

pageB(www.jesse.com/data.js)代碼如下:

<?php  $callback = $_GET['callback'];//得到回調函數名,這里是getData  $data = array('a','b','c');//要返回的數據  echo $callback.'('.json_encode($data).')';//輸出?>

3.document.domain

對于主域相同而子域不同的例子,可以通過設置document.domain的辦法來解決。 具體的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html兩個文件中分別加上 document.domain = "a.com";然后通過a.html文件中創建一個iframe,去控制iframe的contentDocument,這樣兩個js文件之間就可以 “交互”了。當然這種辦法只能解決主域相同而二級域名不同的情況

www.a.com上的a.html

document.domain = 'a.com';var ifr = document.createElement('iframe');ifr.src = 'http://script.a.com/b.html';ifr.style.display = 'none';document.body.appendChild(ifr);ifr.onload = function(){  var doc = ifr.contentDocument || ifr.contentWindow.document;  // 在這里操縱b.html  alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);};

script.a.com上的b.html

document.domain = 'a.com';

4.跨域資源共享(CORS)

原理:跨源資源共享(CORS)定義一種跨域訪問的機制,可以讓AJAX實現跨域訪問。CORS允許一個域上的網絡應用向另一個域提交跨域AJAX請求。實現此功能非常簡單,只需由服務器發送一個響應標頭即可。它是通過客戶端+服務端協作聲明的方式來確保請求安全的。服務端會在HTTP請求頭中增加一系列HTTP請求參數(例如Access-Control-Allow-Origin等),來限制哪些域的請求和哪些請求類型可以接受,而客戶端在發起請求時必須聲明自己的源(Orgin),否則服務器將不予處理,如果客戶端不作聲明,請求甚至會被瀏覽器直接攔截都到不了服務端。服務端收到HTTP請求后會進行域的比較,只有同域的請求才會處理。

pageA(www.jack.com/index.html)代碼如下:

var xhr = new XMLHttpRequest();xhr.onreadystatechange = function(){  if(xhr.readyState === 4 && xhr.status === 200){    console.log(xhr.responseText);  }};xhr.open("get","http://www.jesse.com/data.php");xhr.send(null);

pageB(www.jesse.com/data.php)代碼如下:

<?php  header("Access-Control-Allow-Origin: http://www.jack.com");//與簡單的請求相同  header("Access-Control-Allow-Methods: GET, POST");//允許請求的方法  header("Access-Control-Max-Age: 3628800"); //將這個請求緩存多長時間  $data = array('a','b','c');//要返回的數據  echo json_encode($data);//輸出?>

5.window.postMesage 不常用

window.postMessage(message,targetOrigin) 方法是html5新引進的特性,可以使用它來向其它的window對象發送消息,無論這個window對象是屬于同源或不同源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經支持window.postMessage方法。

pageA(www.jack.com/index.html)代碼如下:

<iframe id="proxy" src="http://www.jesse.com/index.html" onload="postMsg()" style="display: none"></iframe><script type="text/javascript">var obj = {  msg: 'hello world'}function postMsg() {  var iframe = document.getElementById('proxy');  var win = iframe.contentWindow;  win.postMessage(obj, 'http://www.jesse.com');}</script>pageB(www.jesse.com/data.php)代碼如下:<script type="text/javascript">window.onmessage = function(e) {  console.log(e.data.msg + " from " + e.origin);}</script>

6. location.hash 不常用

pageA(www.jack.com/index.html)代碼如下:

function startRequest() {  var ifr = document.createElement('iframe');  ifr.style.display = 'none';  ifr.src = 'http://www.jesse.com/b.html#sayHi'; //傳遞的location.hash   document.body.appendChild(ifr);}function checkHash() {  try {    var data = location.hash ? location.hash.substring(1) : '';    if (console.log) {      console.log('Now the data is ' + data);    }  } catch (e) {};}setInterval(checkHash, 5000);window.onload = startRequest;

pageA(www.jack.com/proxy.html)代碼如下:

parent.parent.location.hash = self.location.hash.substring(1);

pageB(www.jesse.com/b.html)代碼如下:

function checkHash() {  var data = '';  //模擬一個簡單的參數處理操作  switch (location.hash) {    case '#sayHello':      data = 'HelloWorld';      break;    case '#sayHi':      data = 'HiWorld';      break;    default:      break;  }  data && callBack('#' + data);}function callBack(hash) {  // ie、chrome的安全機制無法修改parent.location.hash,所以要利用一個中間的www.a.com域下的代理iframe  var proxy = document.createElement('iframe');  proxy.style.display = 'none';  proxy.src = 'http://www.jack/c.html' + hash; // 注意該文件在"www.jack.com"域下  document.body.appendChild(proxy);}window.onload = checkHash;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 惠来县| 西华县| 广州市| 得荣县| 图木舒克市| 科尔| 策勒县| 洪湖市| 台北县| 高淳县| 阿坝县| 连南| 怀安县| 浮山县| 神池县| 娱乐| 石泉县| 百色市| 济阳县| 子洲县| 光山县| 杭锦旗| 黄骅市| 府谷县| 偏关县| 门头沟区| 龙山县| 加查县| 青田县| 营山县| 土默特右旗| 阿拉善盟| 翼城县| 大兴区| 洛隆县| 贵定县| 公主岭市| 和静县| 庆元县| 界首市| 通城县|