javascript笔记——jsonp

上篇博客介绍了同源策略和跨域访问概念,其中提到跨域常用的基本方式:JSONP和CORS。

那这篇博客就介绍JSONP方式。

 JSONP原理

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。

而JSONP就是通过script节点src调用跨域的请求。

当我们通过JSONP模式请求跨域资源时,服务器返回给客户端一段javascript代码,这段javascript代码自动调用客户端回调函数。

举个例子

客户端http://localhost:8080访问服务器http://localhost:11111/user,正常情况下,这是不允许的。因为这两个URL是不同域的。

若我们使用JSONP格式发送请求的话?

http://localhost:11111/user?callback=callbackfunction

 则服务器返回的数据如下:

callbackfunction({"id":1,"name":"test"})

  

仔细看看服务器返回的数据,其实就是一段javascript代码,这就是函数名(参数)格式。

服务器返回后,则自动执行callbackfunction函数。

因此,客户端需要callbackfunction函数,以便使用JSONP模式返回javascript代码后自动执行其回调函数。

  注意:其中url地址中的callback和callbackfunction是随意命名的。

  

具体的JS实现JSONP代码。

JS中:

[html] view plaincopy

  <script>
  var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction";
  var script = document.createElement(‘script‘);
  script.setAttribute(‘src‘, url);  //load javascript
  document.getElementsByTagName(‘head‘)[0].appendChild(script);   

  //回调函数
   function callbackfunction(data){
var html=JSON.stringify(data.RESULTSET);
alert(html);
     }

 

服务器代码Action:

后台返回的json外面需要由回调函数包裹。具体的方法如下:

[html] view plaincopy

  1. public class TestJson extends ActionSupport{  
    
        @Override
        public String execute() throws Exception {
            try {
                JSONObject jsonObject=new JSONObject();
                List list=new ArrayList();
                for(int i=0;i<4;i++){
                    Map paramMap=new HashMap();
                    paramMap.put("bank_no", 100+i);
                    paramMap.put("money_type", i);
                    paramMap.put("bank_name", i);
                    paramMap.put("bank_type", i);
                    paramMap.put("bank_status", 0);
                    paramMap.put("en_sign_ways", 1);
                    list.add(paramMap);
                }
                JSONArray rows=JSONArray.fromObject(list);
                jsonObject.put("RESULTSET", rows);
                HttpServletRequest request=ServletActionContext.getRequest();
                HttpServletResponse response=ServletActionContext.getResponse();
                response.setContentType("text/javascript");  
    
                boolean jsonP = false;
                String cb = request.getParameter("jsonp");
                if (cb != null) {
                    jsonP = true;
                    System.out.println("jsonp");
                    response.setContentType("text/javascript");
                } else {
                    System.out.println("json");
                    response.setContentType("application/x-json");
                }
                response.setCharacterEncoding("UTF-8");
                Writer out = response.getWriter();
                if (jsonP) {
                    out.write(cb + "("+jsonObject.toString()+")");
                    System.out.println(jsonObject.toString());
                }
                else{
                    out.write(jsonObject.toString());
                     System.out.println(jsonObject.toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }  
    
            return null;
        }
    }
    

      

 JQUERY实现JSONP代码。

Jquery从1.2版本开始也支持JSONP的实现。

[html] view plaincopy

$(function(){
     jQuery.getJSON("http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=?",function(data)
{
  var html=JSON.stringify(data.RESULTSET);
$("#testjsonp").html(html);
}
     );
});

  

第一个?代表后面是参数,与咱们一般调用一样。重要的是第二个?,则是jquery动态给你生成毁掉函数名称。

至于后台代码和上述一致,使用同一个后台。

JQUERY中Ajax实现JSONP代码。

[html] view plaincopy

 $.ajax({
type:"GET",
async :false,
url:"http://localhost:8080/crcp/rcp/t99eidt/testjson.do",
dataType:"jsonp",
success:function(data){
var html=JSON.stringify(data.RESULTSET);
$("#testjsonp").html(html);
},
error:function(){
alert("error");
}  

});

  

注意:这种形式,默认的参数是callback,而不是会是其他。则action代码中获取calback值则

String cb=request.getParameter("callback");

并且生成的回调函数,默认也是类似上述一大串数字。

根据Ajax手册,更改callback名称以及回调函数名称。

    http://www.w3school.com.cn/jquery/ajax_ajax.asp
    jsonp:jsonp,则请求的地址为:http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=自动生成回调函数名
    jsonpCallback:callbackfunction,则请求的地址为:
    http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction
    最后返回前台的是:
    callbackfunction(具体的json值)

  

其中上述JS实现JSONP代码中,若不是动态拼接script脚本,而是直接写script标签,类似如下:

<script type="text/javascript" src=""></script>

若这样写的话,通过debug发现,的确正确返回了,但是一直提示找不到回调函数。即使js也提供了回调函数【各个浏览器都测试】

若要通过JS来显示,则通过代码动态create script标签。

JSONP跨域方式,很方便,同时也支持大多部分浏览器,但是唯一缺点是,只支持GET提交方式,不支持其他POST提交。

若url地址传输的参数过多,如何实现呢?下篇博客会讲解另一种跨域方案CROS原理以及具体调用示例。

本文转载自:http://blog.csdn.net/yuebinghaoyuan/article/details/32706277

时间: 2024-08-28 01:01:02

javascript笔记——jsonp的相关文章

JavaScript笔记之Function

一.函数定义 (1)使用function declaration 格式:function functionName(parameters) { function body } 注:此种方式声明的函数作用域是全局的,即在声明之前可以调用 (2)使用function expression 格式:var name = function (parameters) { function body }; 注:与(1)不同,在声明之前不可以调用 (3)使用function constructor() 格式:v

javascript笔记(二)

concat() 连接多个字符串,返回合并后的字符串. 1 var s1="a"; 2 var s2="b"; 3 var s3="c"; 4 5 console.log(s1.concat(s2,s3));//abc concat() 方法的结果等同于:result = s1 + s2 + ... + sN.如果有不是字符串的参数,则它们在连接之前将首先被转换为字符串. 数组中的concat():将参数添加为数组的元素,返回新的数组. 1 va

[Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+1}" 反射获取函数源代码的功能很强大,使用函数对象的toString方法有严重的局限性.toString方法的局限性ECMAScript标准对函数对象的toString方法的返回结果(即该字符串)并没有任何要求.这意味着不同的js引擎将产生不同的字符串,甚至产生的字符串与该函数并不相关. 如果函数

[Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式传递给eval函数以达到同样的功能.程序员面临一个选择:应该将代码表示为函数还是字符串?毫无疑问,应该将代码表示为函数.字符串表示代码不够灵活的一个重要原因是:它们不是闭包. 闭包回顾 看下面这个图 js的函数值包含了比调用它们时执行所需要的代码还要多的信息.而且js函数值还在内部存储它们可能会引用

[Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //"number" typeof "s";//"string" typeof null;//"object":ECMAScript把null描述为独特的类型,但返回值却是对象类型,有点困惑. 可以使用Object.prototype.t

JavaScript笔记杂谈篇(啥都有)

二维码缩放比例以43PX的倍数缩放最为标准. NuGet相关管理http://www.cnblogs.com/dudu/archive/2011/07/15/nuget.html 学习笔记: http://kb.cnblogs.com/page/143190/ 动态创建标记,给标记添加样式,class,等等   vardtProductName=$("<dt></dt>",{style:"text-overflow: ellipsis;overflow

JavaScript笔记基础篇(二)

基础篇主要是总结一些工作中遇到的技术问题是如何解决的,应为本人属于刚入行阶段技术并非大神如果笔记中有哪些错误,或者自己的一些想法希望大家多多交流互相学习. 1.ToFixed()函数 今天在做Birt报表时, 要显示一列百分比的数据,但因一些特别的原因,不能使用使用百分比样式,即如果数据是0.9538不能显示成“95.38%”的样式,必须显示成“95.38”. 开始时想使用javascript的内置函数Math.round(),可Math.round()只能显示为整数,而不能保留小数. 再网上搜

学习Javascript笔记1 Javascript对象1

以前学过一段时间Js,现在再看,感觉又像是新知识,说明自己对Js掌握的还不是很好(是很不好,从来就没好过,嘿嘿),在这里,在温习一下 如果各位大哥大姐不幸看到了,,额 额这只是自己的笔记. 在Js里面 面向对象的思想是绝对很重要的,大家如果看过大神的代码,就会知道在Js里面面向对象的思想有多么重要了 JavaScript 中的所有事物都是对象:字符串(String).数字(Number).数组(Array).日期(Date),等等. 在 JavaScript 中,对象是拥有属性和方法的数据. 属

原生javascript实现jsonp的封装

JSONP即JSON with Padding.由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名.协议.端口)的资源.如果要进行跨域请求, 我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象. 这种跨域的通讯方式称为JSONP. 我们可以动态的去创建一个script标签,利用他的src属性没有跨域的限制来实现的,相当于我们引入一个js文件 附上源码: jsonp: funct