jsonp解决跨域访问受限问题

本文详细解释了JSON和JSONP的区别及应用场景。介绍了JSON作为一种数据描述格式的优点,并阐述了JSONP作为一种非正式传输协议如何解决跨域访问的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

json和jsonp是两个很容易混淆的概念,再介绍跨域访问之前简单介绍一下这两个概念吧。
1、json是一种应用广泛,而且很简单的数据描述格式,或者说是规则。
优点:1、基于纯文本,跨平台传递极其简单;
2、JavaScript原生支持,后台语言几乎全部支持;
3、轻量级数据格式,占用字符数量极少,特别适合互联网传递;
4、容易编写和解析,当然前提是你要知道数据结构;
json对象采用{}包含,一个对象中包含多个属性(键值对),各属性采用“,”隔开。多个json对象组成一个json数组,采用[]包含,各json对象之间采用“,”隔开。以此类推,层层嵌套!

2、jsonp与json是完全不同的概念,jsonp不是一种数据格式,而是一种非正式传输协议。
1)、一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准;
2)、不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如script、img、iframe等标签);
3)、于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的Html5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;
4)、恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;
5)、这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。
6)、客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但其实并不一样。
7)、为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

jsonp实现跨域访问的原理就是这样了,下面结合实例具体说说。
JavaScript实现:

<script type="text/javascript">
// 得到航班信息查询结果后的回调函数
var flightHandler = function(data){
    alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
};
// 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
// 创建script标签,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script); 
</script>
远程服务器解析url中的参数,并把客户请求的数据采用回调函数名包裹放回给客户端:
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});

基于jQuery的jsonp:

jQuery(document).ready(function(){ 
    $.ajax({
         type: "get",
         async: false,
         url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
         dataType: "jsonp",
         jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
         jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
         success: function(json){
             alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
         },
         error: function(){
             alert('fail');
         }
     });
 });

jquery在处理jsonp类型的ajax时,自动帮你生成回调函数并把数据取出来供success属性方法来调用。

Java服务端封装数据并返回:

public void ajaxRequest(Params params) {
        HttpServletRequest request = ;
        HttpServletResponse response = ;
        response.setContentType("text/plain");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0); 
        response.setCharacterEncoding("UTF-8");                        
        Map<String, String> map = new HashMap<String, String>();
        map.put("result", "content");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            String jsonString = JSONObject.toJSONString(map);//随便使用哪个JSONObject都可以,这里只是转为json格式的字符串就行
            String jsonpCallback = request.getParameter("jsonpCallback");// 客户端请求参数
            out.println(jsonpCallback + "(" + jsonString + ")");// 返回jsonp格式数据
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            out.flush();
            out.close();
        }
    }

在服务端设置response.setHeader(“Access-Control-Allow-Origin”, “*”);即可。
Access-Control-Allow-Origin:* 表示允许任何域名跨域访问。
如果需要指定某域名才允许跨域访问,只需把Access-Control-Allow-Origin:*改为Access-Control-Allow-Origin:允许的域名
例如:response.setHeader(“Access-Control-Allow-Origin”, “http://www.client.com“);

最后说一下jsonp和ajax的本质区别:ajax的核心是通过XmlHttpRequest获取非本页内容(不能跨域),而jsonp的核心则是动态添加

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值