jsonp 详解

JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

Jsonp原理(可以先看 Demo)

首先在客户端注册一个callback,然后把callback的名字传给服务器。此时,服务器先生成 json 数据,然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里。(动态执行回调函数)

Demo 演示

一、服务端:建立 web 工程 test_jsonp_server

服务端监听在 8080 端口。

源码下载地址:https://gitee.com/liupeifeng3514/test_jsonp_server

Servlet
package com.lpf.jsonp;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestJsonpDemo extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public TestJsonpDemo() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 回调函数名
        String callBack = request.getParameter("callback");
        // json数据
        String jsonData = "{\"name\":\"挖坑埋你\"}";
        // jsonp格式的数据
        String jsonp = callBack + "(" + jsonData + ")";
        // 设置头信息
        response.setHeader("Content-type", "application/json;charset=utf-8");
        // 输出jsonp格式的数据
        response.getWriter().println(jsonp);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
web.xml
    <servlet>
        <servlet-name>TestJsonpDemo</servlet-name>
        <servlet-class>com.lpf.jsonp.TestJsonpDemo</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>TestJsonpDemo</servlet-name>
        <url-pattern>/testJsonpDemo</url-pattern>
    </servlet-mapping>

二、客户端:建立 web 工程 test_jsonp_client

客户端监听在 8081 端口。

源码下载地址:https://gitee.com/liupeifeng3514/test_jsonp_client

index_jsonp.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>JSONP 实例</title>
    </head>
<body>

    <div id="divCustomers"></div>

    <script  src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript">  
        function callbackFunction(data) {
            document.getElementById('divCustomers').innerHTML = data.name;
        }
    </script>
    <script type="text/javascript" src="http://127.0.0.1:8080/test_jsonp_server/testJsonpDemo?callback=callbackFunction"></script>
</body>
</html>
index_no_jsonp.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>JSONP 实例</title>
    </head>
<body>

    <div id="divCustomers"></div>

    <script  src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript">  
        $.ajax({  
            url:"http://127.0.0.1:8080/test_jsonp_server/testJsonpDemo?callback=callbackFunction",
            success:function(result) {
                document.getElementById('divCustomers').innerHTML = data.name;
            },  
            timeout:3000
        });
    </script>
</body>
</html>

三、运行,验证

跨域不只是指域名(IP)不同,端口号不同也是跨域(即使域名、IP都相同,但端口号不同)

1、跨域失败

这里写图片描述

这里写图片描述

可以看到服务端正确响应了,也返回了正确的数据,但浏览器禁止对返回的数据进行处理。

2、跨域成功

这里写图片描述

页面正确显示了服务端返回的数据。


参考文章:前端必备HTTP技能之同源策略详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值