您好,登錄后才能下訂單哦!
在認識 跨域 之前,先簡單了解下域名和協議名,比如下面這個 URL
http://mail.163.com/index.html
http:// 協議名,也就是HTTP超文本傳輸協議
mail 服務器名
163.com 域名
mail.163.com 網站名
/ 根目錄
index.html 根目錄下的默認網頁
1、什么是跨域請求?
請求的下一個資源所在的 協議、域名、端口號 三者之一與當前資源不一致就稱為 跨域請求
簡單理解,就是 $.get(url, [data], [callback], [type]) 里面的 url 的協議名、域名 或者 端口號與當前域名不一樣
為了避免晦澀難懂的文字,我們直接上一個小 demo:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <h3>非跨域請求</h3> <button id="btn1">非跨域按鈕</button> <h3>跨域請求</h3> <button id="btn2">跨域按鈕</button> <script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.js"></script> <script> $('#btn1').click(function(obj){ $.get('http://localhost:8081/Ajax/2.php',function(){ console.log('btn1被單擊后發起的XHR請求'); console.log(obj); }) }) $('#btn2').click(function(obj){ $.get('http://dapengtalk.blog.51cto.com/',function(){ console.log('btn2被單擊后發起的XHR請求'); console.log(obj); }) }) </script> </body> </html>
在瀏覽器地址欄輸入“http://localhost:8081/Ajax/cross.html”打開頁面,點擊“非跨域按鈕”,查看控制臺
點擊“跨域按鈕”,查看控制臺,發現 XHR請求失敗了,很明顯,請求的域名不同,這就是典型的跨域
查看 Network,XHR請求發起了,而且狀態碼是200
查看請求頭部消息,顯示有 24 字節的響應消息
查看響應消息,卻顯示“這個請求沒有可用的響應消息”
2、瀏覽器允許 跨域請求嗎?
允許:<img src="跨域的圖片">
允許:<link rel="stylesheet" href="跨域的CSS">
允許:<a href="跨域的鏈接">
允許:<script src="跨域的JS">
禁止:AJAX請求是不允許跨域的!
說明:出于安全考慮,所有的瀏覽器默認都禁止使用XHR異步的跨域請求。
舉個例子,比如上面提到的 img 允許跨域
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <img src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png" alt="百度logo"> </body> </html>
不同協議名、不同域名,網頁正常顯示圖片,說明允許跨域。但是文章一開始的 demo 中,使用 Ajax 發起異步請求的時候,卻是不被允許的。那該怎么辦呢?
3、跨域 解決方案
3-1、設置“Access-Control-Allow-Origin”頭部
還記得嗎?域名和域名對應的ip 也是不允許跨域的,在此基礎上,我們把上面的例子稍作修改:
(盡管是同一個 2.php 頁面,但一個是域名,一個是域名對應的ip)
HTML代碼:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <h3>非跨域請求</h3> <button id="btn1">非跨域按鈕</button> <h3>跨域請求</h3> <button id="btn2">跨域按鈕</button> <script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.js"></script> <script> $('#btn1').click(function(obj){ $.get('http://localhost:8081/Ajax/2.php',function(){ console.log('btn1被單擊后發起的XHR請求'); console.log(obj); }) }) $('#btn2').click(function(obj){ $.get('http://127.0.0.1:8081/Ajax/2.php',function(){ console.log('btn2被單擊后發起的XHR請求'); console.log(obj); }) }) </script> </body> </html>
PHP代碼:
<?php header('Content-Type: application/json; charset=utf8'); $data = ['uname'=>'Tom','age'=>20]; echo json_encode($data);
點擊“非跨域按鈕“,可以正常發起 Ajax 請求
點擊“跨域按鈕”,報錯了,說明這個屬于 跨域
按照控制臺給出的提示,我們在 php 頁面中設置 Access-Control-Allow-Origin 頭部
PHP代碼:
<?php header('Content-Type: application/json; charset=utf8'); // 指定允許其他域名訪問 header('Access-Control-Allow-Origin:*'); $data = ['uname'=>'Tom','age'=>20]; echo json_encode($data);
看到 btn2,真是太難得了,這個也就說明 設置 Access-Control-Allow-Origin 頭部 是可以解決跨域的
3-2、使用 JSONP
基于3-1的示例代碼,我們再來看一個例子:
HTML代碼:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <button id="crossBtn">跨域按鈕</button> <script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.js"></script> <script> function doResponse(obj){ alert(obj.uname+obj.age); } $('#crossBtn').click(function(){ $.ajax({ url:'http://127.0.0.1:8081/Ajax/3.php', success:doResponse }) }) </script> </body> </html>
PHP代碼:
<?php header('Content-Type: application/json'); $data = ['uname'=>'Tom','age'=>20]; $json = json_encode($data); //返回一個json{"":"","":20}' echo 'doResponse('.$json.')';
通過瀏覽器輸入“http://localhost:8081/Ajax/jsonp01.html”打開網頁,這是一個典型的跨域請求,這里可以使用JSONP手段來解決
在$.ajax 方法中有一個 dataType屬性,如果將該屬性設置成 dataType:"jsonp",就能實現跨域
把上面的代碼稍作修改:
HTML代碼:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <button id="crossBtn">跨域按鈕</button> <script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.js"></script> <script> function doResponse(obj){ alert(obj.uname+obj.age); } $('#crossBtn').click(function(){ $.ajax({ url:'http://127.0.0.1:8081/Ajax/3.php', dataType:'jsonp', success:doResponse }) }) </script> </body> </html>
PHP代碼:
<?php header('Content-Type: application/javascript'); $data = ['uname'=>'Tom','age'=>20]; $json = json_encode($data); //'{"":"","":20}' echo 'doResponse('.$json.')';
重新打開頁面,可以拿到數據了
如果想更深入的了解 JSONP 原理,可以查看另一篇文章 《詳解 JSON 和 JSONP》
http://dapengtalk.blog.51cto.com/11549574/1877684
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。