上篇博客介绍了同源策略和跨域访问概念,其中提到跨域常用的基本方式: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中:

  <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外面需要由回调函数包裹。具体的方法如下:

  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的实现。
  第一个?代表后面是参数,与咱们一般调用一样。重要的是第二个?,则是jquery动态给你生成毁掉函数名称。

至于后台代码和上述一致,使用同一个后台。
 
JQUERY中Ajax实现JSONP代码。
 $.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

javascript笔记——jsonp的更多相关文章

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

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  2. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  3. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

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

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

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

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  6. 从头开始学JavaScript 笔记(一)——基础中的基础

    原文:从头开始学JavaScript 笔记(一)--基础中的基础 概要:javascript的组成. 各个组成部分的作用 . 一.javascript的组成   javascript   ECMASc ...

  7. 【原】javascript笔记之Array方法forEach&map&filter&some&every&reduce&reduceRight

    做前端有多年了,看过不少技术文章,学了新的技术,但更新迭代快的大前端,庞大的知识库,很多学过就忘记了,特别在项目紧急的条件下,哪怕心中隐隐约约有学过一个方法,但会下意识的使用旧的方法去解决,多年前ES ...

  8. Javascript的jsonp原理

    Javascript的jsonp原理   首先JSON是一种基于文本的数据交换方式,或者叫做数据描述格式 当一个网页在请求JavaScript文件时则不受是否跨域的影响,凡是拥有”src”这个属性的标 ...

  9. JavaScript笔记目录

    JavaScript笔记目录 一.JavaScript简介 二.在HTML中使用JavaScript ...持续更新中,敬请期待

随机推荐

  1. C#窗体间通讯的几种处理方法

    应用程序开发中,经常需要多窗体之间进行数据通信,写几个例子,把几种常用的通信方式总结一下: 主窗体Form1是一个ListBox,单击选中某列时,弹出窗体Form2,Form2中两个控件,一个是Tex ...

  2. node.js小工具--修改Xcode 'Create by'作者名称

    简介 用Xcode创建源文件时会自动在文件开始位置加入如下注释: // // ISSImageCycleScrollView.m // SoftTravel // // Created by iss1 ...

  3. C语言经典算法100例(二)

    11.判断某一年是否是闰年. //判断某一年份是否是闰年 int IsLeapYear(int year) { return (year % 400 == 0 || (year % 4 == 0) & ...

  4. Centos 6.5使用Bumblebee关闭N卡,冷却你的电脑

    夏天来了,笔记本装的Centos一直非常热.随着天气的变化,这个问题真的要攻克了.差了下原因可能是双显卡笔记本,N卡驱动不完好,导致风扇狂叫. 昨天安装了nvidia 的显卡驱动本以为时间安静了.但是 ...

  5. Redis 安全

      我们可以通过 redis 的配置文件设置密码参数,这样客户端连接到 redis 服务就需要密码验证,这样可以让你的 redis 服务更安全. 实例 我们可以通过以下命令查看是否设置了密码验证: 1 ...

  6. 关于直接创建视图UITableViewController显示(初学)

    今天渣渣想直接创建一个UITableView视图作为根视图来用结果发现有警告,才明白TableView和view是不能直接作为根视图的,需要放在ViewController上.做个笔记详细了解下. 参 ...

  7. Autowired properities class

    1. Properties类 @ConfigurationProperties(locations = "classpath:build.properties") @JsonInc ...

  8. 阿里云ubuntu搭建SVN服务器

    系统:Ubuntu 14.04 64位 新手注意:连接到服务器之后,默认会在用户文件夹位置“~”,使用cd /命令可以回到根目录.SVN搭在公共的位置比较稳妥. 1.通过apt-get安装subver ...

  9. LeetCode 319

    Bulb Switcher There are n bulbs that are initially off. You first turn on all the bulbs. Then, you t ...

  10. 修改ie版本的注册表webbroswer

    Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Exp ...