zoukankan      html  css  js  c++  java
  • 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(这部分会在后文浏览器支持部分介绍)。
  • 相关阅读:
    【leetcode】Maximum Subarray
    【USACO】
    【leetcode】Remove Duplicates from Sorted Array
    【leetcode】Path Sum II
    【leetcode】Swap Nodes in Pairs
    【leetcode】Word Ladder
    【leetcode】Copy List with Random Pointer
    【leetcode】Longest Palindromic Substring
    #ifdef #endif #if #endif
    tar [options] [list of file]
  • 原文地址:https://www.cnblogs.com/ccorz/p/5969737.html
Copyright © 2011-2022 走看看