首先:什么是跨域?
Cross Domain Request:從一個資源請求另一個資源,二者所在的請求地址不同,域名不同、端口號不同、請求協議不同。
它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript施加的安全限制。
關於同源策略 這里推薦感興趣的可以去 阮大的博客查看 阮一峰的個人博客
如何區分當前的請求是跨域請求?
在前端使用XHR對象發起請求時 瀏覽器 會將請求的發送地址和請求地址 的 協議 域名 端口號 做 字符串的匹配
提示:localhost和127.0.0.1也算跨域!
瀏覽器允許跨域請求的情形:
IMG、LINK、SCRIPT、IFRAME ...
瀏覽器禁止跨域請求的情形:
XHR —— 瀏覽器處於安全考慮,禁用了XHR的跨域請求(其實服務器給出了響應消息,但瀏覽器不讓使用)
如何解決瀏覽器的XHR跨域請求限制?
網上有關解決跨域請求的方法五花八門,這里僅僅列出常用的兩種
1)、修改響應消息頭部,添加Access-Control-Allow-Origin頭部 服務器端添加響應頭部
2)、使用JSONP
JSONP:JSON with Padding,填充式JSON,與JSON完全兩碼事,是一種使用JSON數據的方式。意思是在JSON字符串左右添加函數名: doResponse( {"ename":"Tom", "age":20} );
JSONP是專用於解決XHR跨域限制一種手段。基本原理:使用動態創建的一個SCRIPT標簽代替XHR發起異步請求,要求服務器必須返回application/javascript,立即在客戶端執行——要執行的函數本體在客戶端瀏覽器中聲明。
<script src="x.php" async></script>
通常我們使用 script 標簽獲取並執行一段js代碼 而scrip標簽和所以擁有src屬性的元素一樣 不受瀏覽器同源策略的影響;
如果我們請求的是 doResponse( data ) 同時本地創建了一個 doResponse 函數
結果 就是直接調用了 doResponse 函數 並在其參數組中獲得了 我們需要的數據 data
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>...</title> <style> </style> </head> <body> <h3>使用JSONP解決瀏覽器跨域問題</h3> <hr> <button id="btn">發送jsonp請求</button> <script type="text/javascript" src="../js/jquery-1.11.3.js"></script> <script type="text/javascript"> $("#btn").click(function(){ var scri = docuemnt.createElement("script"); s.src="http://localhost/AJAX/JSONP/1_jsonp.php"; s.async=true; }); </script> </body> </html>
jQuery中如何使用JSONP發起異步請求:
(1) $.getJSON()
用途1:使用XHR發起異步請求(不能跨域)
$.getJSON('x.php', doResponse)
用途2:使用JSONP發起跨域異步請求
$.getJSON('http://跨域地址/x.php?callback=?', doResponse)
(2) $.ajax() 推薦
用途1:使用XHR發起異步請求(不能跨域)
$.ajax({ })
用途2:使用JSONP發起跨域異步請求
$.ajax({ dataType: 'jsonp' })
jquery 中極度簡化了 script 獲取后端響應數據的過程 但原理都是一樣的;