JSONP的使用

8352次阅读 600人点赞 作者: WuBin 发布时间: 2021-04-22 16:50:53
扫码到手机查看

使用<script>标签从远程获取js文件的思路,可以变通为从其他服务器获取JSON文件。不过这样需要对服务器的json文件做修改。(受同源策略的影响,浏览器从其他服务器无法取得其他服务器的json数据)。

从服务器返回JSONP

back-jsonp.php文件:

<?php 
header("content:application/json;chartset=uft-8");

$callback = isset($_GET['getjsonp']) ? $_GET['getjsonp'] : die('必须提供查询字段名称');

// 包裹json字符串的函数名
$funcName = 'jsonp_callback';

// 
if ($callback !== $funcName) {
    exit('函数名称不正确');
}

$res = [
    'code' => 0,
    'msg' => '返回成功',
    'data' => array(
        'title' => '这是一个标题',
        'desc' => '这是描述',
        'list' => array(
            '这是新闻1',
            '这是新闻2',
            '这是新闻3'
        )
    )
];

$json = json_encode($res, JSON_UNESCAPED_UNICODE);

// jsonp_callback({$json});
$jsonp = "{$funcName}({$json})";

echo $jsonp;

// 在当前目录下生成一个静态的js文件,用于html文件请求的
$filepath = str_replace('\\', '/', __DIR__);
$filename = $filepath . '/' . 'back-jsonp.js';
$file = file_put_contents($filename, $jsonp);
if (!$file) {
    exit('生成js文件失败');
}

JSONP的格式是吧标准的JSON文件包装在一对圆括号中,圆括号又前置一个任意字符串。这个字符串即所谓的P(填充,padding)。由于有一对圆括号,因此返回的数据在客户端可能会有一次函数调用,或者为某个变量赋值。在php实现jsonp非常简单:

echo 'callback_funcName(' . $json . ')';

在前端获取JSONP的方法上,我推荐一个插件:jsonp,点击跳转到github地址。生成后的格式,请见(五)

使用JSONP函数

<script src="jsonp.js"></script>
<script>
    // 请求的地址是:back-jsonp.php?getjsonp=getjsonp_callback
    jsonp(
        'back-jsonp.php',  // url
        // opts
        {
            // 请求的查询字段名称
            param: 'getjsonp', 
            // 包裹json数据的函数名,必须要前后端一致起来
            // 后台也可以使用$_GET动态的名称,这个根据需要
            name: 'jsonp_callback'
        },
        // 注意 返回的是两个值 第一个代表失败,第二个代表成功后的数据
        function(err, data) {
            console.log('使用jsonp函数', data);
        }
    );
</script>

其中name属性比较重要,必须要跟后台包裹json字符串的函数名统一起来,否则会报错,进入失败的获取状态。而param如果后台不做限制,要求并不高,设置可以忽略此参数,让后台的$_GET['..']去自动赋予。

使用JQ

<!-- 下面使用JQ -->
<script src="http://vip.qdxin.cn/navmenu/js/jxinq111.js"></script>
<script>
    // 请求的地址是:back-jsonp.php?getjsonp=jsonp_callback
    // 缺点是无法捕获失败的回调
    $.ajax({
        type: 'GET',
        url: 'back-jsonp.php',
        dataType: 'jsonp',
        // 请求的查询字段名称,如果后台做了限制,那么就必须一致,否则不做要求
        jsonp: 'getjsonp',
        // 包裹json数据的函数名, 默认是jq自动生成的随机名,必须前后端一致才能获取到数据
        jsonpCallback: 'jsonp_callback'
    })
    .done(function(data) {
        console.log('使用JQ的函数', data);
    })
    .fail(function(err) {
        console.log('使用JQ的函数,出错了', err);
    });
</script>

Vue中使用JSONP函数

vue-cli中进行安装  $ npm install jsonp
// 对Jsonp函数的一次封装
import jsonp from 'jsonp';

function getJsonP(url) {
  return new Promise((resolve, reject) => {
    jsonp(
        url,
        {
          name: 'ztcallback'
        },
        (err, data) => {
          if (!err) {
            resolve(data);
          } else {
            reject(err);
          }
        }
    )
  });
}

export default getJsonP;
// 如何使用 : 使用jsonp请求数据解决跨域问题
import getJsonP from "common/js/getJsonP";

return getJsonP(url).then(res => {
  return Promise.resolve(res);
}).catch(err => {
  return Promise.reject(err);
})

从静态JS文件中中获取JSONP

后台有些需求比较奇葩的,比如获取数据原本从库中获取,但是非要求将json生成静态的json文件进行获取等等。因此就有了将JSONP字符串生成静态的js文件这种需求。具体生成的方法请参考一、从服务器返回jsonp。生成的JS文件如下(back-jsonp.js):

jsonp_callback({
    "code":0,
    "msg":"返回成功",
    "data": { 
        "title":"这是一个标题",
        "desc":"这是描述",
        "list":  ["这是新闻1","这是新闻2","这是新闻3"]
    }
});

使用JQ获取静态JS

// 请求的地址是:back-jsonp.js?whatever=jsonp_callback
// 缺点是无法捕获失败的回调
$.ajax({
    type: 'GET',
    url: 'back-jsonp.js',
    dataType: 'jsonp',
    // 请求的查询字段名称,如果后台做了限制,那么就必须一致,否则不做要求
    jsonp: 'whatever',
    // 包裹json数据的函数名, 默认是jq自动生成的随机名,必须前后端一致才能获取到数据,否则会执行错误的数据
    jsonpCallback: 'jsonp_callback'
})
.done(function(data) {
    console.log('使用JQ的函数', data);
})
.fail(function(err) {
    console.log('使用JQ的函数,出错了', err);
});

使用JSONP函数获取静态js

// 请求的地址是:back-jsonp.js?whatever=jsonp_callback
jsonp(
    'back-jsonp.js',  // url
    // opts
    {
        // 请求的查询字段名称
        param: 'whatever', 
        // 包裹json数据的函数名, 当需要从静态的js文件中获取jsonp数据时候
        // 这个字段的名称必须与静态文件中的一致
        name: 'jsonp_callback'
    },
    // 注意 返回的是两个值 第一个代表失败,第二个代表成功后的数据
    function(err, data) {
        console.log('使用jsonp函数', data);
    }
);

当从静态js文件中获取jsonp的时候,只要关注静态文件中的函数名与jsonp函数: name, JQ的jsonpCallback一致即可。而查询字段就不那么重要了,是什么都行。

最后补充一句:附件的案例,请在服务器环境下运行。

附件下载

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:jsonp
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    8186次阅读 521人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3282次阅读 241人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    13228次阅读 854人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12104次阅读 385人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    10347次阅读 829人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    14248次阅读 1132人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14180次阅读 1156人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    27073次阅读 2131人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    23237次阅读 1791人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录