jsonp学习探究

示例地址:https://download.csdn.net/download/yzy85/10461053

1、jsonp原理

javascript、ajax访问页面基于同源策略,对于非同一协议、主机或者端口的不同页面,js不能直接访问,会提示跨域访问的错误提示。

为了能够跨域调用函数,需要使用具备跨域属性的方式,而我们知道,html页面引用js文件时,例如<head>标签内的jquery文件,可以通过<script>的src属性引用非同源的文件,此时就能跨域调用,其他有src属性的标签<script><img><iframe> 都能跨域访问其他文件。

因此jsonp的实现核心就是利用script标签的跨域能力,利用提供的url(即动态生成的script标签的src),调用服务器提供的文件或者方法,最终生成返回的都是一段可执行的js代码

如果要调用非同源的文件获取数据,此时我们可以利用  <script>的标签的这一特性,将后台页面方法生成的json数据存放到返回的文件流中,并利用<script>加载到页面<head>标签内。但是直接返回json数据浏览器不能正确执行,因此还需要将json数据作为参数包含到函数中,当带参数的函数加载到浏览器并解析成功后,浏览器即执行该函数,完成从非同源页面跨域获取数据的过程。

这种利用src属性加载文件调用服务端方法获取数据的方式即是jsonp方式,JSONP  是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback 或者开始就定义一个回调方法,参数给服务端,然后服务端返回数据时会将这个callback 参数作为函数名来包裹住 JSON  数据,返回到浏览器时执行,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

其他解释:jsonp原理:

  1. 首先在客户端注册一个callback, 然后把callback的名字传给服务器。
  2. 服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
  3. 客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
   

2、jsonp实现方式

用到的html代码,我们依次测试3种实现方式:

    <input type="button" id="btn1" value="点击获取jsonp" οnclick="getJsonp()" /><input type="text" id="txt1" value="" />
    <input type="button" id="btn2" value="Jquery点击获取jsonp" /><input type="text" id="txt2" value="" />
    <input type="button" id="btn3" value="Jquery($.ajax)点击获取jsonp" /><input type="text" id="txt3" value="" />
    <input type="button" id="btn4" value="Jquery($.getScript)点击获取jsonp" /><input type="text" id="txt4" value="" />

C# 后台方法

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Web.Script.Serialization;

public class Handler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        string studentCode = context.Request.QueryString["code"];
        string callback = context.Request.QueryString["callback"];

        var msg = new { message = "收到!" };
        string result = new JavaScriptSerializer().Serialize(msg);
        context.Response.Write(callback + "(" + result + ")");
        //context.Response.Write(result);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

2.1 javascript原生方式,将url调用直接加入到<script>标签的src属性,然后将<script>加入页面文档中,此时需要提供后台方法需要的参数以及callback页面回调方法,用于包裹返回的json数据。

按钮btn1点击将触发getJsonp函数,增加<script>标签,待返回getBackValue调用,其中getBackValue()函数需要提前定义。

       function getBackValue(json) {
            document.getElementById("txt").value = json.message;
        }

        function getJsonp() {
            var url = 'Handler.ashx?code=CA1998&callback=getBackValue';
            var script = document.createElement('script');
            script.setAttribute('src', url);
            document.getElementsByTagName('head')[0].appendChild(script);
        }

返回js内容:

2.2、为简化开发,jquery对jsonp进行了封装,封装在了jquery.ajax中函数中。通过定义dataType: 'jsonp'并传递url,参数,回调方法等,执行成功后再success函数中进行下一步处理。其中jsonp参数会包含在get参数中传输到服务器,可以不定义,默认为“callback”,如果定义其它名称,后台方法取get参数的时候也要使用定义的其它名称,jsonpCallback是要回调的函数名称,可定义(返回后直接执行),也可不定义(从jquery提供的默认函数中提取参数在success函数中执行),并且值不能为空,jquery调用完成后会从该函数中提取json数据。

      $(function () {
            $('#btn2').on('click', function (event) {
                event.preventDefault();
                $.ajax({
                    type: 'GET',
                    async: false,
                    url: 'Handler.ashx',
                    data: { "code": "CA1998" },
                    dataType: 'jsonp',
                    jsonp: 'callback',//后台QueryString[“callback”],可改为其他字符串
                    jsonpCallback: 'getBackValue',  // 若未定义,默认为jQuery自动生成的随机函数名
                    success: function (json) {
                        document.getElementById("txt2").value = json.message;
                    },
                    error: function (error) {
                        alert('fail');
                    }
                });
            });

返回内容:

使用该方式调用网络上其他公司提供的api,并且jsonpCallback使用jquery提供的默认值,jquery版本号+随机数字

           $('#btn3').bind('click', function (event) {
                event.preventDefault();
                $.ajax({
                    type: 'GET',
                    async: false,
                    url: 'https://www.sojson.com/open/api/kuaidi/get.shtml',
                    data: { "orderNo": "887180351164743887" },
                    dataType: 'jsonp',
                    jsonp: 'callback',
                    //jsonpCallback: 'getJsonp',  // 默认为jQuery自动生成的随机函数名
                    success: function (json) {
                        document.getElementById("txt3").value = json.data[0].info;
                    },
                    error: function (error) {
                        alert('fail');
                    }
                });
            });


或者直接使用$.get函数通过jsonp方式调用,返回同上

    $('#btn4').bind('click', function (event) {
                $.get('https://www.sojson.com/open/api/kuaidi/get.shtml?orderNo=887180351164743887', function (json) {
                    console.log(json);
                    document.getElementById("txt4").value = json.data[0].info;
                }, 'jsonp');
            });

2.3 使用jquery.getScript()函数并传入后台方法参数和回调函数名称,跨域调用Javascript文件并返回调用脚本,返回同上

      $('#btn4').bind('click', function (event) {
                event.preventDefault();
                $.getScript("https://www.sojson.com/open/api/kuaidi/get.shtml?orderNo=887180351164743887&callback=testjsonp4");
                //或者
                $.getScript("Handler.ashx?code=CA1998&callback=getBackValue");
            });
function testjsonp4(json) {
            document.getElementById("txt4").value = json.data[0].info;
        }





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值