专栏名称: 前端JavaScript
分享 | 学习 | 交流 | 原创 分享是学习的开始;学习不必要从头开始,是从现在开始;交流能沟通你我,提高你的学识;期待你的加入!!! web前端技术交流,JavaScript,HTML5,CSS3……
目录
相关文章推荐
51好读  ›  专栏  ›  前端JavaScript

【第3章第360回】利用Jsonp实现跨域请求,spring MVC+JQuery

前端JavaScript  · 公众号  · Javascript  · 2017-06-04 16:46

正文


1 什么是Jsonp?

JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。另一个解决这个问题的新方法是跨来源资源共享。


由于同源策略,一般来说位于www.42du.cn的网页无法与不是 www.42du.cn的服务器沟通,而HTML的 < script >元素是一个例外。利用 < script >元素的这个开放策略,网页可以得到从其他来源动态产生的JSON数据,而这种使用模式就是所谓的JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。


2 Jsonp基本原理

为了理解这种模式的原理,先想像有一个回传JSON文件的URL,而JavaScript 程序可以用XMLHttpRequest跟这个URL要数据。假设我们的URL是 http://tools.42du.cn/jsonp/student/3/em。假设iFat3的st_no是3,当浏览器通过URL传递iFat3的st_id,也就是抓取http://tools.42du.cn/jsonp/student/3/em,得到:


{"st_no":3,"st_name":"iFat3","st_desc":"iFat3是学校的超级学渣"}

这个JSON数据可能是依据传过去URL的查询参数动态产生的。


这个时候,把 < script >元素的src属性设成一个回传JSON的URL是可以想像的,这也代表从HTML页面通过script元素抓取 JSON是可能的。


然而,一份JSON文件并不是一个JavaScript程序。为了让浏览器可以在 < script >元素运行,从src里URL 回传的必须是可运行的JavaScript。在JSONP的使用模式里,该URL回传的是由函数调用包起来的动态生成JSON,这就是JSONP的“填充(padding)”或是“前辍(prefix)”的由来。


惯例上浏览器提供回调函数的名称当作送至服务器的请求中命名查询参数的一部分,例如:


 

服务器会在传给浏览器前将JSON数据填充到回调函数(callback)中。浏览器得到的回应已不是单纯的数据叙述而是一个脚本。在本例中,浏览器得到的是:


/**/callback({"st_no":3,"st_name":"iFat3","st_desc":"iFat3是学校的超级学渣"});


3 服务端生成Jsonp

本例中的Jsonp利用的是Spring Framework的JSonp处理部分生成,详细内容请阅读官方文档。链接见相关资料中的spring部分,本人强烈建意您在实际开发过程中,先阅读官方文档,再进行代码编写。


3.1 模型(model)对象


Student模型对象的get和set方法未列出。


public class Student extends BaseBean implements Serializable {

    private Integer st_no;

    private String st_name;

    private String st_desc;

}

3.2 spring的Jsonp处理


@ControllerAdvice

@RequestMapping("/jsonp")

public class StudentJsonpAdvice extends AbstractJsonpResponseBodyAdvice {

    private List students = new ArrayList();

    public StudentJsonpAdvice() {

        super("callback");

        initData();

    }

    @RequestMapping(value="/student/all",method= RequestMethod.GET)

    @ResponseBody

    public List list(){

        return students;

    }

    @RequestMapping(value="/student/{st_no}",method= RequestMethod.GET)

    @ResponseBody

    public Student info(@PathVariable Integer st_no){

        if(st_no != null) {

            if(st_no > 0 && st_no <4) {

                return students.get(st_no -1);

            }

            return students.get(0);

        }

        return null;

    }

    private void initData() {

        Student st1 = new Student(1,"王美丽","王美丽是学校的校花");

        Student st2 = new Student(2,"毛三胖","毛三胖是学校的学霸");

        Student st3= new Student(3,"iFat3","iFat3是学校的超级学渣");

        students.add(st1);

        students.add(st2);

        students.add(st3);

    }

}


4 客户端取得Jsonp数据

利用JQuery的ajax方法取得所有学生的数据,并利用回调函数(callback)将数据插入到页面中。更多JQuery的ajax方法参见相关资料中的JQuery部分。


function callback(data) {

        $(data).each(function(i,item){

            $("#stu_ul").append("

  • "+item.st_name+"
  • ");

            });

        }

        $(document).ready(function () {

            $.ajax({

                type:"get",

                dataType:"jsonp",

                url:"http://tools.42du.cn/jsonp/student/all",

                jsonpCallback:"callback"

            });

        })


    5 相关资料

    Spring处理Jsonp文档

    http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-jsonp

    JQuery Ajax官方文档

    http://api.jquery.com/jQuery.ajax/

    维基Jsonp条目

    https://zh.wikipedia.org/wiki/JSONP

    菜鸟Jsonp教程

    http://www.runoob.com/json/json-jsonp.html

    JSON中文介绍

    http://www.json.org/json-zh.html

    学生列表Jsonp地址

    http://tools.42du.cn/jsonp/student/all

    学生信息Jsonp地址

    http://tools.42du.cn/jsonp/student/3


    转自: https://segmentfault.com/a/1190000009650105

    作者: 毛三胖


    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    如果文章不错,请转发的朋友圈!

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


    ==========阅读原文==========