日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js跨域解决方式

發布時間:2024/4/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js跨域解决方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是跨域?

概念:僅僅要協議、域名、port有不論什么一個不同,都被當作是不同的域。(所謂同源是指,域名。協議,port同樣。),對于port和協議的不同,僅僅能通過后臺來解決。

URL 說明 是否同意通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 同意 http://www.a.com/lab/a.js http://www.a.com/script/b.js 同一域名下不同目錄 同意 http://www.a.com:8000/a.js http://www.a.com/b.js 同一域名,不同port 不同意 http://www.a.com/a.js https://www.a.com/b.js 同一域名,不同協議 不同意 http://www.a.com/a.js http://70.32.92.74/b.js 域名和域名相應ip 不同意 http://www.a.com/a.js http://script.a.com/b.js 主域同樣,子域不同 不同意 http://www.a.com/a.js http://a.com/b.js 同一域名。不同二級域名(同上) 不同意(cookie這樣的情況下也不同意訪問) http://www.cnblogs.com/a.js http://www.a.com/b.js 不同域名 不同意


1、跨域資源共享(CORS)

CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問跨域資源時,瀏覽器與server應該怎樣溝通。

CORS背后的基本思想就是使用自己定義的HTTP頭部讓瀏覽器與server進行溝通。從而決定請求或響應是應該成功還是失敗。

server端對于CORS的支持。主要就是通過設置Access-Control-Allow-Origin來進行的。

假設瀏覽器檢測到對應的設置。就能夠同意Ajax進行跨域的訪問。

比如:客戶端的域名是www.client.com,而請求的域名是www.server.com

在被請求的Response header中增加

[php]?view plain?copy ?
  • //?指定同意其它域名訪問??
  • header('Access-Control-Allow-Origin:*');??
  • //?響應類型??
  • header('Access-Control-Allow-Methods:POST');??
  • //?響應頭設置??
  • header('Access-Control-Allow-Headers:x-requested-with,content-type');??
  • 就能夠實現ajax POST跨域訪問了。



    代碼例如以下:

    client.html?路徑:http://www.client.com/client.html

    [html]?view plain?copy ?
  • <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN">??
  • <html>??
  • ?<head>??
  • ??<meta?http-equiv="content-type"?content="text/html;charset=utf-8">??
  • ??<title>?跨域測試?</title>??
  • ??<script?src="//code.jquery.com/jquery-1.11.3.min.js"></script>??
  • ?</head>??
  • ??
  • ?<body>??
  • ????<div?id="show"></div>??
  • ????<script?type="text/javascript">??
  • ????$.post("http://www.server.com/server.php",{name:"fdipzone",gender:"male"})??
  • ??????.done(function(data){??
  • ????????document.getElementById("show").innerHTML?=?data.name?+?'?'?+?data.gender;??
  • ??????});??
  • ????</script>??
  • ?</body>??
  • </html>??

  • server.php?路徑:http://www.server.com/server.php

    [php]?view plain?copy ?
  • <?php??
  • $ret?=?array(??
  • ????'name'?=>?isset($_POST['name'])??$_POST['name']?:?'',??
  • ????'gender'?=>?isset($_POST['gender'])?

    ?

    $_POST['gender']?:?''??
  • );??
  • ??
  • header('content-type:application:json;charset=utf8');??
  • header('Access-Control-Allow-Origin:*');??
  • header('Access-Control-Allow-Methods:POST');??
  • header('Access-Control-Allow-Headers:x-requested-with,content-type');??
  • ??
  • echo?json_encode($ret);??
  • ?>??

  • Access-Control-Allow-Origin:*?表示同意不論什么域名跨域訪問

    假設須要指定某域名才同意跨域訪問,僅僅需把Access-Control-Allow-Origin:*改為Access-Control-Allow-Origin:同意的域名

    比如:header('Access-Control-Allow-Origin:http://www.client.com');


    假設須要設置多個域名同意訪問。這里須要用php處理一下

    比如同意 www.client.com 與 www.client2.com 能夠跨域訪問

    server.php 改動為

    [php]?view plain?copy ?
  • <?

    php??

  • $ret?=?array(??
  • ????'name'?=>?isset($_POST['name'])?

    ?

    $_POST['name']?:?'',??
  • ????'gender'?=>?isset($_POST['gender'])??$_POST['gender']?:?''??
  • );??
  • ??
  • header('content-type:application:json;charset=utf8');??
  • ??
  • $origin?=?isset($_SERVER['HTTP_ORIGIN'])??$_SERVER['HTTP_ORIGIN']?:?'';??
  • ??
  • $allow_origin?=?array(??
  • ????'http://www.client.com',??
  • ????'http://www.client2.com'??
  • );??
  • ??
  • if(in_array($origin,?$allow_origin)){??
  • ????header('Access-Control-Allow-Origin:'.$origin);??
  • ????header('Access-Control-Allow-Methods:POST');??
  • ????header('Access-Control-Allow-Headers:x-requested-with,content-type');??
  • }??
  • ??
  • echo?json_encode($ret);??
  • ?> ?


  • 要解決跨域的問題。我們能夠使用下面幾種方法:

    2、通過jsonp跨域

    如今問題來了?什么是jsonp?維基百科的定義是:JSONP(JSON with Padding)是資料格式?JSON?的一種“使用模式”,能夠讓網頁從別的網域要資料。

    JSONP也叫填充式JSON,是應用JSON的一種新方法。僅僅只是是被包括在函數調用中的JSON。比如:

    callback({"name","trigkit4"});

    JSONP由兩部分組成:回調函數和數據。

    回調函數是當響應到來時應該在頁面中調用的函數,而數據就是傳入回調函數中的JSON數據。

    在js中,我們直接用XMLHttpRequest請求不同域上的數據時,是不能夠的。可是,在頁面上引入不同域上的js腳本文件卻是能夠的,jsonp正是利用這個特性來實現的。

    ?比如:

    <script type="text/javascript">function dosomething(jsondata){//處理獲得的json數據} </script> <script src="http://example.com/data.php?

    callback=dosomething"

    ></script>

    js文件加載成功后會運行我們在url參數中指定的函數,而且會把我們須要的json數據作為參數傳入

    所以jsonp是須要server端的頁面進行對應的配合的。

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

    終于。輸出結果為:dosomething(['a','b','c']);

    假設你的頁面使用jquery,那么通過它封裝的方法就能非常方便的來進行jsonp操作了。

    <script type="text/javascript"> $.getJSON('http://example.com/data.php?callback=?

    ,function(jsondata)'

    ){ //處理獲得的json數據 }); </script>

    jquery會自己主動生成一個全局函數來替換callback=?

    中的問號,之后獲取到數據后又會自己主動銷毀,實際上就是起一個暫時代理函數的作用。$.getJSON方法會自己主動推斷是否跨域,不跨域的話,就調用普通的ajax方法;跨域的話,則會以異步載入js文件的形式來調用jsonp的回調函數。

    JSONP的優缺點

    JSONP的長處是:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中都能夠執行。不須要XMLHttpRequest或ActiveX的支持;而且在請求完成后能夠通過調用callback的方式回傳結果。

    JSONP的缺點則是:它僅僅支持GET請求而不支持POST等其他類型的HTTP請求。它僅僅支持跨域HTTP請求這樣的情況,不能解決不同域的兩個頁面之間怎樣進行JavaScript調用的問題。

    CORS和JSONP對照

    CORS與JSONP相比,無疑更為先進、方便和可靠。

    1、 JSONP僅僅能實現GET請求,而CORS支持全部類型的HTTP請求。

    2、

    使用CORS,開發人員能夠使用普通的XMLHttpRequest發起請求和獲得數據。比起JSONP有更好的錯誤處理。

    3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS)。


    3、通過改動document.domain來跨子域

    瀏覽器都有一個同源策略,其限制之中的一個就是第一種方法中我們說的不能通過ajax的方法去請求不同源中的文檔。 它的第二個限制是瀏覽器中不同域的框架之間是不能進行js的交互操作的。
    不同的框架之間是能夠獲取window對象的。但卻無法獲取對應的屬性和方法。比方,有一個頁面,它的地址是http://www.example.com/a.html?, 在這個頁面里面有一個iframe,它的src是http://example.com/b.html, 非常顯然,這個頁面與它里面的iframe框架是不同域的,所以我們是無法通過在頁面中書寫js代碼來獲取iframe中的東西的:

    <script type="text/javascript">function test(){var iframe = document.getElementById('ifame');var win = document.contentWindow;//能夠獲取到iframe里的window對象,但該window對象的屬性和方法差點兒是不可用的var doc = win.document;//這里獲取不到iframe里的document對象var name = win.name;//這里相同獲取不到window對象的name屬性} </script> <iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

    這個時候,document.domain就能夠派上用場了,我們僅僅要把http://www.example.com/a.html?和http://example.com/b.html這兩個頁面的document.domain都設成同樣的域名就能夠了。但要注意的是。document.domain的設置是有限制的,我們僅僅能把document.domain設置成自身或更高一級的父域,且主域必須同樣。

    (1).在頁面?http://www.example.com/a.html?中設置document.domain:

    <iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe> <script type="text/javascript">document.domain = 'example.com';//設置成主域function test(){alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗體的 window 對象} </script>

    (2).在頁面?http://example.com/b.html?中也設置document.domain:

    <script type="text/javascript">document.domain = 'example.com';//在iframe加載這個頁面也設置document.domain,使之與主頁面的document.domain同樣 </script>

    改動document.domain的方法僅僅適用于不同子域的框架間的交互。


    4、使用window.name來進行跨域

    window對象有個name屬性。該屬性有個特征:即在一個窗體(window)的生命周期內,窗體加載的全部的頁面都是共享一個window.name的,每一個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗體加載過的全部頁面中的。

    樣例:

    特將詳細實現方法記錄例如以下:

    如a.com站點想通過JS獲取b.com站點的數據。

    (1) 在a.com站點加入一個空HTML頁。

    名稱為:http://a.com/null.html

    (2) 在a.com站點須要獲取數據頁面(如:http://a.com/getDomainData.html)內容例如以下:

    <!DOCTYPE?html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html?xmlns="http://www.w3.org/1999/xhtml" > <head> ????<title>跨域獲取數據</title> ????<script?type="text/javascript"> ????function domainData(url, fn) ????{ ????????var isFirst = true; ????????var iframe = document.createElement('iframe'); ????????iframe.style.display = 'none'; ????????var loadfn = function(){ ????????????if(isFirst){ ????????????????iframe.contentWindow.location = 'http://a.com/null.html'; ????????????????isFirst = false; ????????????} else { ????????????????fn(iframe.contentWindow.name); ????????????????iframe.contentWindow.document.write(''); ????????????????iframe.contentWindow.close(); ????????????????document.body.removeChild(iframe); ????????????????iframe.src = ''; ????????????????iframe = null; ????????????} ????????}; ????????iframe.src = url; ????????if(iframe.attachEvent){ ????????????iframe.attachEvent('onload', loadfn); ????????} else { ????????????iframe.onload = loadfn; ????????} ????????? ????????document.body.appendChild(iframe); ????} ????</script> </head> <body> </body> ????<script?type="text/javascript"> ????domainData('http://b.com/data.html', function(data){ ????????alert(data); ????}); ????</script> </html>

    (3) 在b.com中加入獲取數據頁面 如:http://b.com/data.html 內容需包括:?

    <script>   window.name = '須要跨域傳遞的數據'; </script>

    (4) 訪問 http://a.com/getDomainData.html 就可返回?http://b.com/data.html 中的window.name中的數據了。

    須要注意的地方

    null.html 是必須的。內容可為空。

    ?iframe的onload事件綁定 必須這樣寫:

    if(iframe.attachEvent){ ?????iframe.attachEvent('onload', loadfn); }else?{ ?????iframe.onload = loadfn; }

    調用domainData函數必須在body后面,或頁面載入完后。

    調用時會運行?http://b.com/data.html 頁面的腳本。


    ?

    5、使用HTML5的window.postMessage方法跨域

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


    ?

    轉載于:https://www.cnblogs.com/brucemengbm/p/7363746.html

    總結

    以上是生活随笔為你收集整理的js跨域解决方式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。