zoukankan      html  css  js  c++  java
  • ajax跨域问题-----jsonp

    1.浏览器的同源策略:域名,协议,端口均相同,叫做同源

    举个例子:

    http://www.123.com/index.html 调用 http://www.123.com/server.PHP (非跨域)
    
    http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
    
    http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)
    
    http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)
    
    http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)
    
    请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

    2.跨域:浏览器不能执行其他网站的脚本

    3.解决跨域的方法:

    (1)JSONP

    JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

      将JSON数据填充进回调函数

    举个例子:

    www.test1.com域名A下有一个文件A:a.html

    <!DOCTYPE html>
    <html lang="zh-cmn-Hans">
    <head>
       <meta charset="utf-8">
        <meta name="keywords" content="">
        <meta name="description" content="">
        <meta name="author" content="author">
        <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
        <meta name="apple-mobile-web-app-title" content="">
        <meta name="apple-mobile-web-app-capable" content="yes"/>
        <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
        <meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">
        <meta name="format-detection" content="telphone=no, email=no"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <!--remove weixin's cache -->
        <meta http-equiv="Pragma" content="no-cache">
        <meta http-equiv="Cache-Control" content="no-cache">
        <meta http-equiv="Expires" content="0">
        <title>a.html</title>
    
       <script type="text/javascript" src="http://test2.com/test.js"></script> 
    </head>
    <body>
    
    </body>
    </html>

    www.test2.com域名B下有一个文件B,test.js:

    alert("success")

    域名A想访问域名B,

    <script type="text/javascript" src="http://test2.com/test.js"></script> 
    若如上调用,则可以访问到
    若如下调用,则不可访问到,因为浏览器跨域了。

    <script type="text/javascript" src="./test.js"></script> 

    --那如何通过jsonp来访问到test.js呢?

    ----jsonp简单小例子:

    a.html:

    <!DOCTYPE html>
    <html lang="zh-cmn-Hans">
    <head>
       <meta charset="utf-8">
        <title></title>
        
      <script type="text/javascript">
    //创建一个回调函数
           function callback(data) {
        alert(data.message);
    }
       </script>
       <script type="text/javascript" src="http://test2.com/test.js"></script> 
    </head>
    <body>
    
    </body>
    </html>

    test.js:

    //调用callback函数,并以json数据形式作为阐述传递,完成回调
    callback({message:"success"}); 

    好了,完成一个jsonp的小例子,这样做,域名A就可以访问域名B中的test.js了。但是这样的话,test.js是在html还没加载完就已经弹出信息了,很不方便。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务

    ----动态创建script标签,实现jsonp

    a.html:

    <!DOCTYPE html>
    <html lang="zh-cmn-Hans">
    <head>
       <meta charset="utf-8">
        <title></title>
        
      <script type="text/javascript">
    //添加<script>标签的方法
        function addScriptTag(src){
            var script = document.createElement('script');
            script.setAttribute("type","text/javascript");
            script.src = src;
            document.body.appendChild(script);
        }
        
        window.onload = function(){
            //搜索apple,将自定义的回调函数名result传入callback参数中
            //为了方便演示:假设test.js为http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=result
          //此链接是服务端已经设置好jsonp的获取文件
    addScriptTag("http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=result"); } //自定义的回调函数result function result(data) { //我们就简单的获取apple搜索结果的第一条记录中url数据 alert(data.postalcodes[0].adminCode2); } </script> </head> <body> </body> </html>
    http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=回调函数名
    callback=回调函数名,就是你在a.html文件里写的自定义回调函数result

    此处再强调一遍jsonp:

    JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

      将JSON数据填充进回调函数

    jQuery对jsonp的实现(转)

    jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法(详细可以参考http://api.jquery.com/jQuery.getJSON/)。那我们就来修改下程序A的代码,改用jQuery的getJSON方法来实现(下面的例子没用用到向服务传参,所以只写了getJSON(url,[callback])):

    复制代码
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
    $.getJSON("http://localhost:20002/MyService.ashx?callback=?",function(data){
    alert(data.name + " is a a" + data.sex);
    });
    </script>
    复制代码

      结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。这个函数名大家可以debug一下看看,比如jQuery17207481773362960666_1332575486681。

      当然,加入说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现(参数较多,详细可以参考http://api.jquery.com/jQuery.ajax)。先来看看如何实现吧:

    复制代码
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
    $.ajax({
    url:"http://localhost:20002/MyService.ashx?callback=?",
    dataType:"jsonp",
    jsonpCallback:"person",
    success:function(data){
    alert(data.name + " is a a" + data.sex);
    }
    });
    </script>
    复制代码

      没错,jsonpCallback就是可以指定我们自己的回调方法名person,远程服务接受callback参数的值就不再是自动生成的回调名,而是person。dataType是指定按照JSOPN方式访问远程服务。

    (2)跨域解决方法2----代理:

    例如www.123.com/index.html需要调用www.456.com/server.php,可以写一个接口www.123.com/server.php,由这个接口在后端去调用www.456.com/server.php并拿到返回值,然后再返回给index.html,这就是一个代理的模式。相当于绕过了浏览器端,自然就不存在跨域问题。

     

    (3)跨域解决方法3----PHP端修改header(XHR2方式)

    在php接口脚本中加入以下两句即可:

    header('Access-Control-Allow-Origin:*');//允许所有来源访问

    header('Access-Control-Allow-Method:POST,GET');//允许访问的方式

  • 相关阅读:
    android-6
    android-5
    android-购物商城
    安卓简易计算器
    安卓第四周作业
    安卓第一周作业
    第十五周作业
    第十三周作业
    第十三周上机练习
    第三次安卓作业
  • 原文地址:https://www.cnblogs.com/lanyueff/p/6950697.html
Copyright © 2011-2022 走看看