JSONP 跨域访问

一、 跨域访问

在某个A网站中,我们希望使用Ajax来获得某个B网站中的特定内容。如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题。

二、JSONP

JSONP(JSON With Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。

一般来说位于 serverA.example.com 的网页无法与不是 serverB.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用<script>元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

三、JSONP的使用实例

1、前端Ajax发送请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp test</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script>
    <script type="text/javascript">

    function apitest(){ 

        $.ajax({
            url :'http://localhost:1000/test',//访问的链接
            type : "GET", // 请求方式
            dataType:"jsonp",// 从后端返回的数据类型
            crossDomain:true,//是否跨域
            jsonpCallback:"callback",//为JSONP请求指定的callback函数的名称
            jsonp:"callback",//跨域函数名的键值,即服务端提取函数名的key(默认为callback)
            success: function(data) { 请求成功的回调函数,data为要获得的数据
                var html = "<p>"+JSON.stringify(data)+"</p>";//object to detail
                $("#data-detail").html(html); 
                // console.log(data);
                // alert(JSON.stringify(data));
            },
            error: function(data) {//请求失败的回调函数
                alert( "error" );
            }
        });
    }

</script>

</head>
<body>
<h1>Get data with ajax</h1>
<input type="button" value="get data" onclick="apitest()">
<div id="data-detail"></div>
</body>
</html>

2、后端响应请求

#设置response的contentType
@RequestMapping(value = {"/test"},method = RequestMethod.GET,produces = "text/javascript;charset=UTF-8")
public String getJsonp(@RequestParam("callback") String callback,
                           HttpServletResponse response) {
    #设置response的header
    response.setHeader("Access-Control-Allow-Origin","*");
    
    Map<String,String> data=new HashMap<>();
    data.put("test","1");
    //构造返回值
    callback + "(" + JSONArray.toJSONString(data,SerializerFeature.WriteMapNullValue) + ")";  
}

(1)response的contentType类型

ajax开发中在请求服务器端的响应时, 对于每一种返回类型,需要在服务端指定response的contentType ,常遇到下面的几种情况:
a. 服务端需要返回一段普通文本给客户端,Content-Type=”text/plain”
b. 服务端需要返回一段HTML代码给客户端 ,Content-Type=”text/html”
c. 服务端需要返回一段XML代码给客户端 ,Content-Type=”text/xml”
e. 服务端需要返回一段javascript代码给客户端,Content-Type=”text/javascript”
f. 服务端需要返回一段json串给客户端,,Content-Type=”text/json”

需要注意:spring mvc不能使用response.setHeader("Content-Type", "text/javascript; charset=UTF-8");设置contentType,设置了虽然不会报错,但不会生效。

原因:参考这篇文章:https://www.cnblogs.com/kaiblog/p/7565231.html

设置方法:

@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {
    // implementation omitted
}

(2)response header其他信息

 response.setHeader("Access-Control-Allow-Origin","*");// 指定允许其他域名访问

 response.setHeader("Access-Control-Allow-Methods","GET,POST");// 响应类型

(3)to json

当value为null时,JSONObject.toJSONString()返回的json字符串将不展示对应的key。

可以使用JSONObject.toJSONString(Object object, SerializerFeature... features) ,其中SerializerFeature属性对应的值和含义如下:

a. QuoteFieldNames    输出key时是否使用双引号,默认为true     
b. UseSingleQuotes    使用单引号而不是双引号,默认为false     
c. WriteMapNullValue    是否输出值为null的字段,默认为false     
e. WriteEnumUsingToString    Enum输出name()或者original,默认为false     
f. UseISO8601DateFormat    Date使用ISO8601格式输出,默认为false     
j. WriteNullListAsEmpty    List字段如果为null,输出为[],而非null     
h. WriteNullStringAsEmpty    字符类型字段如果为null,输出为”“,而非null     
i. WriteNullNumberAsZero    数值字段如果为null,输出为0,而非null     
j. WriteNullBooleanAsFalse    Boolean字段如果为null,输出为false,而非null     
k. SkipTransientField    如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true     
l. SortField    按字段名称排序后输出。默认为false     
m. WriteTabAsSpecial    把\t做转义输出,默认为false  
n. PrettyFormat    结果是否格式化,默认为false     
o. WriteClassName    序列化时写入类型信息,默认为false。反序列化是需用到     
p. DisableCircularReferenceDetect    消除对同一对象循环引用的问题,默认为false     
q. WriteSlashAsSpecial    对斜杠’/’进行转义     
r. BrowserCompatible    将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false     
s. WriteDateUseDateFormat    全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);

参考文章:

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

https://www.cnblogs.com/kaiblog/p/7565231.html

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值