Ajax_05之跨域請求

来源:http://www.cnblogs.com/Jupiter258/archive/2016/11/11/6053187.html
-Advertisement-
Play Games

1、跨域請求: Cross Domain Request:跨功能變數名稱的HTTP請求,瀏覽器從某個功能變數名稱下的資源訪問了另一功能變數名稱下的另一資源(協議、功能變數名稱或是埠號不同); ①瀏覽器允許跨域請求的情形: <img>、<link>、<script>、<iframe> ②禁止跨域請求的情形: XHR——瀏覽器預設出 ...


1、跨域請求:
 Cross Domain Request:跨功能變數名稱的HTTP請求,瀏覽器從某個功能變數名稱下的資源訪問了另一功能變數名稱下的另一資源(協議、功能變數名稱或是埠號不同);
 ①瀏覽器允許跨域請求的情形:
  <img>、<link>、<script>、<iframe>
 ②禁止跨域請求的情形:
  XHR——瀏覽器預設出於安全考慮,禁止XHR跨域請求;
 ③相關名詞及解決方案:
  a、相同域:兩個具有相同的協議(如:http)、相同的埠(如:80)、相同的host(主機名),即為相同域,否則構成跨域;
  b、file協議:用於訪問本地電腦中的文件;
  c、同源策略:跨域之間的腳本是隔離的,一個域中的腳本不能訪問、操作另一個域的絕大部分屬性和方法;同源策略應對一些特殊情況做處理,例:限制file協議下腳本的訪問許可權,本地的HTML文件在瀏覽器中是通過file協議打開的,若腳本能通過file協議訪問到硬碟上的其他任意文件,就會出現安全隱患;
  d、單向跨域之JSONP:JSON with Padding;
   原理:由於HTML中的script標簽可以載入執行其它域的javascript,所以可以通過script標記動態載入其它域的資源;
   實現:在pageB中以javascript的形式聲明pageA所需的數據,然後在pageA中用script標簽將 pageB載入進來,JSONP在此基礎上加入回調函數,pageB載入完後會執行pageA中定義的函數,所需數據以參數形式傳遞給該函數;
   限制:JSONP適合在受信任的雙方傳遞數據,否則易被第三方腳本篡改頁面內容,截獲敏感數據;
   代碼:
   function handleResponse(response){
       console.log('The responsed data is: '+response.data);
   }
   var script = document.createElement('script');
   script.src = 'http://www.baidu.com/json/?callback=handleResponse';
   document.body.insertBefore(script, document.body.firstChild);
   /*handleResonse({"data": "zhe"})*/
   //原理如下:
   //當我們通過script標簽請求時
   //後臺就會根據相應的參數(json,handleResponse)
   //來生成相應的json數據(handleResponse({"data": "zhe"}))
   //最後這個返回的json數據(代碼)就會被放在當前js文件中被執行
   //至此跨域通信完成
  e、單向跨域之flash URLLoader:
   原理:flash有自己的安全策略,伺服器可以通過crossdomain.xml文件聲明能被哪些域的SWF文件訪問,SWF也可以通過API確定自身能被哪些域的SWF載入,跨域訪問時,可藉助flash發送HTTP請求;
   實現:先修改域中crossdomain.xml,將其加入白名單,然後通過Flash URLLoader發送HTTP請求,通過Flash API將響應結果傳遞給javascript;
   限制:不支持IOS;
  f、單向跨域之Access Control:
   原理:瀏覽器發送跨域的HTTP請求,請求包含一個Access-Control-Allow-Origin的HTTP響應頭部,該響應頭聲明瞭請求域的可訪問許可權;
   實現:給被跨域訪問的資源添加響應消息頭部,設定允許來自某個功能變數名稱下的頁面訪問當前頁面:header('Access-Control-Allow-Origin:http://xxx.xx');
   限制:少數瀏覽器支持(Firefox、Chrome通過XMLHttpRequest,IE8通過XDomainRequest發送請求);
  g、單向跨域之window.name:
   原理:當window的location變化,重新載入,name屬性依然保持不變;
   實現:在pageA中用iframe載入其它域的pageB,在pageB中用javascript把需要傳遞的數據賦值給window.name,iframe載入完成後,pageA修改iframe的地址為同域的一個地址,即可讀出window.name的值;
   代碼:
   請求代理:
   <head>
       <script>
      function proxy(url, func){
        var isFirst = true,
            ifr = document.createElement('iframe'),
            loadFunc = function(){
              if(isFirst){
                ifr.contentWindow.location = 'http://a.com/cs1.html';
                isFirst = false;
              }else{
                func(ifr.contentWindow.name);
                ifr.contentWindow.close();
                document.body.removeChild(ifr);
                ifr.src = '';
                ifr = null;
              }
            };

        ifr.src = url;
        ifr.style.display = 'none';
        if(ifr.attachEvent) ifr.attachEvent('onload', loadFunc);
        else ifr.onload = loadFunc;

        document.body.appendChild(iframe);
      }
    </script>
   </head>
   <body>
     <script>
       proxy('http://www.baidu.com/', function(data){
         console.log(data);
       });
     </script>
   </body>
   響應:
   <script>
       window.name = '要傳送的內容';
   </script>
  h、單向跨域之server proxy:
   原理:在數據提供方沒有提供對JSONP或window.name協議的支持,也沒有對其它域開放訪問許可權時,可使用server proxy(伺服器代理)方式抓取數據,跨域的HTTP請求在伺服器端進行,客戶端不用產生跨域的Ajax請求;
   實現:在伺服器配置一個代理,將Ajax請求綁定到這個代理路徑下,然後由這個代理髮送Http請求去訪問文件;
   限制:該跨域方式不需要和目標資源簽訂協議,帶有侵略性,另需對該代理實施一定程度的保護,如限制他人使用或使用頻率;
  i、雙向跨域之document.domain:
   原理:同域策略認為域和子域屬於不同的域,修改document的domain屬性為同一host,可以在域和子域或不同子域間通信;
   實現:將不同子域document的domain屬性修改為同一host,瀏覽器會認為它們處於同一域下,此時即可互相調用對方的method來通信;
   代碼:
   請求:
   document.domain = 'a.com';
   var ifr = document.createElement('iframe');
   ifr.src = 'http://www.script.a.com/b.html';
   ifr.display = none;
   document.body.appendChild(ifr);
   ifr.onload = function(){
       var doc = ifr.contentDocument || ifr.contentWindow.document;
       //在這裡操作doc,也就是b.html
       ifr.onload = null;
   };
   響應:
   document.domain = 'a.com';
  j、雙向跨域之FIM:
   原理:Fragment Identiter Messaging,父視窗與iframe可以相互讀寫URL,URL中“#”號及其後面的字元被稱為frag,它一般用於瀏覽器錨點定位,HTTP請求中不會攜帶frag,每個window通過改變其他window的location來發送消息,並通過監聽自己的URL變化來接收消息;
   限制:這種方式通信會產生不必要的瀏覽器歷史記錄,且有些瀏覽器不支持onhashchange事件,需要用輪詢來獲知URL的改變,另URL在瀏覽器下有長度限制,制約了每次傳送的數據量;
  k、雙向跨域之Flash LocalConnection:
   原理:Flash API中有LocalConnection類,該類允許兩個SWF之間進行通信,SWF可以播放在獨立的Flash Player或者AIR中,也可以嵌套在HTML頁面或者PDF中;
   實現:在不同域的HTML頁面各自嵌套一個SWF來相互傳遞數據;
   限制:數據量有40kb的大小限制,且過程複雜,實用性不強;
  l、雙向跨域之window.postMessage:
   HTML5定義的新方法,可跨window通信,在較舊瀏覽器中無法使用;
   代碼:
   請求:
   <iframe id="ifr" src="b.com/index.html"></iframe>
   <script type="text/javascript">
    window.onload = function() {
        var ifr = document.getElementById('ifr');
        var targetOrigin = 'http://b.com';  // 若寫成'http://b.com/c/proxy.html'效果一樣
                 // 若寫成'http://c.com'就不會執行postMessage了
        ifr.contentWindow.postMessage('I was there!', targetOrigin);
    };
   </script>
   響應:
   <script type="text/javascript">
       window.addEventListener('message', function(event){
           // 通過origin屬性判斷消息來源地址
           if (event.origin == 'http://a.com') {
               alert(event.data);    // 彈出"I was there!"
               alert(event.source);  // 對a.com、index.html中window對象的引用
                     // 但由於同源策略,這裡event.source不可以訪問window對象
           }
       }, false);
   </script>
  m、雙向跨域之Cross Frame:
   原理:FIM的變種,藉助空白iframe,不會產生多餘瀏覽器歷史記錄,也不需要輪詢URL的改變;域中pageA和空白代理頁proxyA,另一個域pageB和其空白代理頁proxyB,pageA向pageB發送消息時頁面創建隱藏的iframe,iframe的src指向proxyB,並把message作為URL frag;pageB和proxyB是同域,iframe載入完成後,pageB可以獲得iframe的URL,解析出message,並移除iframe;反向同理;
   限制:Opera無法使用,但可使用window.postMessage;
  n、動態創建script:
   function loadScript(url, func) {
     var head = document.head || document.getElementByTagName('head')[0];
     var script = document.createElement('script');
     script.src = url;

     script.onload = script.onreadystatechange = function(){
       if(!this.readyState || this.readyState=='loaded' || this.readyState=='complete'){
         func();
         script.onload = script.onreadystatechange = null;
       }
     };

     head.insertBefore(script, 0);
   }
   window.baidu = {
     sug: function(data){
       console.log(data);
     }
   }
   loadScript('http://suggestion.baidu.com/su?wd=w',function(){console.log('loaded')});
   //我們請求的內容在哪裡?
   //我們可以在chorme調試面板的source中看到script引入的內容
  o、Web Socket:
   原理:web sockets是一種瀏覽器的API,它的目標是在一個單獨的持久連接上提供全雙工、雙向通信,在JS創建了web socket之後,會有一個HTTP請求發送到瀏覽器以發起連接。取得伺服器響應後,建立的連接會使用HTTP升級從HTTP協議交換為web sockt協議;
   代碼:
   var socket = new WebSockt('ws://www.baidu.com');//http->ws; https->wss
   socket.send('hello WebSockt');
   socket.onmessage = function(event){
       var data = event.data;
   }
   限制:只有在支持web socket協議的伺服器上才能正常工作;
2、jQuery中發起JSONP請求的方法:
 ①$.getJSON兩種方法:
  a、使用XHR接收伺服器端返回的JSON響應:
   $.getJSON('x.php',function(obj){});
  b、使用script標簽執行伺服器返回的script響應——JSONP:
   $.getJSON('http://其他功能變數名稱/x.php?callback=?',doResponse);
 ②$.ajax的兩種方法:
  a、使用XHR接收伺服器端返回的響應:
   $.ajax({});
  b、使用script標簽執行伺服器返回的script響應——JSONP:
   $.ajax({
    type:'GET',
    url:'x.php',
    data:{k:v},
    dataType:'jsonp',//設定伺服器端返回JSONP數據
    success:fn
   });

* 本篇內容部分自網上整理而來,請原作者勿怪!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當一個HTML元素需要添加mouseon、mouseout與click事件,或者mouserenter、mouseleave和click事件時,click事件無法觸發 針對上述問題,我遇到的有兩種情況: 情況一:已經存在的HTML元素綁定事件,可以使用下麵這種綁定方式 情況二:未來存在的要素綁定事件 ...
  • 最近在寫一個時間判斷腳本,需要將固定好的字元串時間轉換為時間戳進行比較,在做的時候個人習慣使用chrome作為調試工具, 代碼基本完成之後,一切正常; 使用其他瀏覽器訪問,好嘛,IE跟safari都不相容,返回錯誤"Invalid Date"。 想著估計是字元串格式的問題,改成'2016/11/11 ...
  • ...
  • 公司對於搭建本地私有npm庫有如下要求: 私有包托管在內部伺服器中 項目中使用了公共倉庫上的公共包,也使用了內部伺服器上的私有包 希望下載的時候,公共包走公共倉庫,私有包走內部伺服器的私有倉庫 伺服器硬碟有限,希望只緩存下載過的包,而不是全部同步。 ... ...
  • 關於egret接入第三方庫的方法,egret也有文檔,可參考官方的接入方法接入http://developer.egret.com/cn/github/egret-docs/extension/threes/instructions/index.html。 這裡記錄一下接入puremvc庫的過程,關 ...
  • 在複習廖雪峰老師的JS教程時,看到數組,又遇到了之前做過的那道小題,題目如下: 練習:在新生歡迎會上,你已經拿到了新同學的名單,請排序後顯示:歡迎XXX,XXX,XXX和XXX同學!: 給出了數組: 這道題作為一個練習並不是很難,當時自己第一次看也是按照最直接的辦法,使用了${arr[i]}來拿到對 ...
  • Redux就是個數據中心,不依附於任何框架在哪使用都行。但是和它最搭配的應該就是React了,而且大家學習它的動力大多也是解決React狀態管理的問題。都說Redux文檔詳盡清晰,但我感覺並不友好,它沒有用最簡單直觀的方式告訴你如何搭配React使用。研究了兩天的文檔和示例,終於在項目中用上了我認為 ...
  • 目前 "AlloyFinger" 作為騰訊手機QQ web手勢解決方案,在各大項目中都發揮著作用。 感興趣的同學可以去Github看看: "https://github.com/AlloyTeam/AlloyFinger" 在騰訊,如:興趣部落、QQ群、QQ動漫、騰訊學院、TEDxTencent、 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...