JSONP實現Ajax跨域請求


前言

由於瀏覽器存在同源策略的機制,所謂同源策略就是阻止從一個源(域名,包括同一個根域名下的不同二級域名)加載的文檔或者腳本獲取/或者設置另一個源加載的文檔屬性.

但比較特別的是:由於同源策略是瀏覽器的限制,所以請求的響應和發送是可以進行的,只不過瀏覽器不支持罷了.

同源策略限制

瀏覽器的同源策略並不是對所有的請求都有限制的:

  • 限制: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(這部分會在后文瀏覽器支持部分介紹)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM