前端跨域调用--JSONP

前端跨域调用–JSONP

标签(空格分隔): 淘淘商城


之前一直比较关注后端的RPC组件,支持跨系统之间的调用,对于前端的调用,只对Ajax请求有印象,但Ajax是不能跨域调用的。这边就要使用JsonP技术,其实JsonP谈不上是一个新技术,只是一个跨域请求的解决方案,利用了JavaScript的一个漏洞来完成跨域请求。
首先说下什么是跨域调用:

  1. 域名不同
  2. 域名相同,端口不同

JsonP的原理

在前端开发中,页面都会引入很多js、css静态文件,也可以在线引入一些其他网站的静态资源,域名和我们所在域名不一样,但不影响使用,说明网页对静态资源的跨域请求是没问题的。但是在Ajax请求发送请求之后,服务端也是可以正常的接收请求并作出相应。如下图所示:
这里写图片描述
客户端代码:

$.ajax({
 url : "http://sso.taotao.com/service/user/query/" + _ticket,
 type : "GET",
 success : function(data){
    if(data){
     var _data = data;
     var html =_data.username+",欢迎来到淘淘!<a href=\"http://www.taotao.com/user/logout.html\" class=\"link-logout\">[退出]</a>";
     $("#loginbar").html(html);
                }
            }
        });

在浏览器的“NetWork”中找到:http://sso.taotao.com/service/user/query/这个请求,发现相应状态为:200,但控制台报错:

Failed to load http://sso.taotao.com/service/user/query/c823e36c0a20cff4ab5a3b3ac20669a6: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.taotao.com' is therefore not allowed access.

原因是:服务端不管你请求的来源,只管相应,但是当数据经过浏览器的时候,浏览器判断出js访问的数据来源不同的域,于是便拒绝将数据返回到页面中,所以报上面的错。请求如下图所示:
这里写图片描述
那如何解决这个问题呢?我们先看一个例子:
1、在jsp中返回一个json数据,然后在另外一个页面中请求:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
    out.print("{\"abc\":123}");
%>

前端访问代码为:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="http://static.taotao.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
    <title></title>
</head>
<script>
    alert($);
    $(function(){$.ajax({
            url :"http://manager.taotao.com/rest/page/jsonp",
            dataType:"json",
            type : "GET",
            success : function(data){
                alert(data.abc);
            }
        })
    });
</script>
<body>
</body>
</html>

结果:
alert($)可以正常输出,但是ajax请求报错,错误信息和上面的一模一样,出现了跨域问题

Failed to load http://manager.taotao.com/rest/page/jsonp: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

**结论:scprit标签的src可以支持跨域资源,但是ajax不可以出现跨域。
思路:可否借助script标签来进行加载数据呢?—可以的**

2、修改jsp代码如下:

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="http://static.taotao.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
    <title></title>
</head>
<script>
    alert($);
    /*$(function(){$.ajax({
            url :"http://manager.taotao.com/rest/page/jsonp",
            dataType:"json",
            type : "GET",
            success : function(data){
                alert(data.abc);
            }
        })
    });*/
</script>
<script type="text/javascript" src="http://manager.taotao.com/rest/page/jsonp"></script>
<body>

**结果:请求资源可以正常请求,但是js解析出错。
原因:scpript加载资源后,会对资源进行js解析,但是我们返回的不是js而是json数据
解决:只需要把返回的数据封装成js就行了。**

3、将后台返回的数据封装成js即可。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
    out.print("fun({\"abc\":123});");
%>

测试结果:
这里写图片描述

报错:Uncaught ReferenceError: fun is not defined
at jsonp:2
这个错误就比较清楚了,表示:fun方法没有定义,那我们在页面上定义一个方法:

function fun(data){
        alert(data.abc);
    }
</script>
<script type="text/javascript" src="http://manager.taotao.com/rest/page/jsonp"></script>

测试结果:可以正常弹出

**结论:1、jsonp通过script标签的src可以跨域请求的特性加载资源
2、将加载的资源当做一个js脚本解析(通过一个方法名将数据进行包裹)
3、定义一个函数作为回调函数,获取传入的数据**

JsonP怎么解决这个问题呢?

综合上面的原理,我们就可以使用如下方式,先看图:
这里写图片描述

步骤:1、通过script发起资源请求,请求中声明回调函数的方法名
2、定义回调函数
3、服务端处理之后,返回一个将回调函数包装之后的符合js语法的字符串。


—– 这样就解决了前端跨域请求的问题了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值