解決ajax跨域問題(1)jsonp
阿新 • • 發佈:2018-12-05
https://www.cnblogs.com/ccorz/p/5969737.html
前言
由於瀏覽器存在同源策略的機制,所謂同源策略就是阻止從一個源(域名,包括同一個根域名下的不同二級域名)載入的文件或者指令碼獲取/或者設定
另一個源載入的文件屬性.
但比較特別的是:由於同源策略是瀏覽器的限制,所以請求的響應和傳送是可以進行的,只不過瀏覽器不支援罷了.
同源策略限制
瀏覽器的同源策略並不是對所有的請求都有限制的:
- 限制:XmlHttpRequest
- 不限制:img iframe script等等具有src屬性的標籤
利用src屬性標籤實現跨域請求
基本思路
利用script標籤,src匯入目標域名的介面,在文件數的head標籤中新增一行script標籤,得到內容後將scprit標籤刪除,返回的解析後的引數即為得到的資料.
利用script標籤實現跨域程式碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>Index</h1> <input type="button" onclick="Ajax();" value="普通AJax"/> <input type="button" onclick="Ajax2();" value="跨域普通AJax"/> <input type="button" onclick="Ajax3();" value="跨域牛逼AJax"/> <input type="button" onclick="Ajax4();" value="江西TV"/> <script src="/static/jquery-2.1.4.min.js"></script> <script> // 原生ajax,測試無效 function Ajax(){ $.ajax({ url: '/get_data/', type: 'POST', data: {'k1': 'v1'}, success: function (arg) { alert(arg); } }) } // 使用ajax跨域請求,測試無效 function Ajax2(){ $.ajax({ url: 'http://wupeiqi.com:8001/api/', type: 'GET', data: {'k1': 'v1'}, success: function (arg) { alert(arg); } }) } // 利用script標籤,得到資料 function Ajax3(){ // script // alert(api) var tag = document.createElement('script'); tag.src = 'http://wupeiqi.com:8001/api/'; document.head.appendChild(tag); document.head.removeChild(tag); } function fafafa(arg){ console.log(arg); } // 例子,獲取江西衛視的節目單 function Ajax4(){ // script // alert(api) var tag = document.createElement('script'); tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'; document.head.appendChild(tag); document.head.removeChild(tag); } function list(arg){ console.log(arg); } </script> </body> </html>
JSONP實現ajax跨域
以上的程式碼其實也是jsonp的基本思路
基本的jsonp寫法
$.ajax({ url:.. type: 'GET', dataType: 'jsonp', //傳遞給請求處理程式或頁面的,用以獲得jsonp回撥函式名的引數名(一般預設為:callback) jsonp: 'callback', //自定義的jsonp回撥函式名稱,預設為jQuery自動生成的隨機函式名,也可以寫"?",jQuery會自動為你處理資料 jsonpCallback: 'list' }) function list(arg){ }
解釋:
jsonp: callback #傳送給請求處理程式的,被請求端通過request.GET.get("callback"),獲得jsonp回撥函式的引數
jsonpCallback: 'list' #定義回撥函式的名稱,然後後面通過list(...)來處理獲取資料
生產示例
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>
<input type="button" onclick="Jsonp1();" value='提交'/>
</p>
<p>
<input type="button" onclick="Jsonp2();" value='提交'/>
</p>
<script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function Jsonp1(){
var tag = document.createElement('script');
tag.src = "http://c2.com:8000/test/";
document.head.appendChild(tag);
document.head.removeChild(tag);
}
function Jsonp2(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'GET',
dataType: 'JSONP',
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
}
</script>
</body>
</html>
###基於JSONP實現跨域Ajax - Demo
JSONP不能傳送POST請求
究其根源,通過script標籤的src屬性進行跨域請求,<script src='http://www.jxntv.cn/data/jmd-jxtv2.html?callback=qwerqweqwe&_=1454376870403'>
最後全部都會轉換成GET請求,哪怕是你把type改為POST
.
別處copy的例子,供參考
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<script type="text/javascript" src=jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
$.ajax({
type: "get",
async: false,
url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回撥函式名的引數名(一般預設為:callback)
jsonpCallback:"flightHandler",//自定義的jsonp回撥函式名稱,預設為jQuery自動生成的隨機函式名,也可以寫"?",jQuery會自動為你處理資料
success: function(json){
alert('您查詢到航班資訊:票價: ' + json.price + ' 元,餘票: ' + json.tickets + ' 張。');
},
error: function(){
alert('fail');
}
});
});
</script>
</head>
<body>
</body>
</html>
其他ajax跨站請求方式
需要順帶提一句的是,跨站請求還有另一種方式:cors
,跨站資源共享,但此中方式對瀏覽器版本有要求,IE8以下的均不支援.
CORS與JSONP相比,無疑更為先進、方便和可靠。
1、 JSONP只能實現GET請求,而CORS支援所有型別的HTTP請求。
2、 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得資料,比起JSONP有更好的錯誤處理。
3、 JSONP主要被老的瀏覽器支援,它們往往不支援CORS,而絕大多數現代瀏覽器都已經支援了CORS(這部分會在後文瀏覽器支援部分介紹)。