美文网首页
JSONP跨域请求的小尝试

JSONP跨域请求的小尝试

作者: yandaxin | 来源:发表于2020-07-17 18:47 被阅读0次

众所周知,为了安全性考虑浏览器是不支持跨域请求的,哪些请求是跨域请求?
什么是跨域请求
总之,同源是指 协议、域名、端口都相同,否则都算跨域。

本文用JSONP的方式实现了一个小小的跨域请求demo,在<script>标签中请求另外一台服务器的脚本,回调函数拿到数据后渲染echart,蛮有意思。

效果如图:


test559是我的开发机

//board.html
获取到url传参date后,拼接为src链接地址,动态生成一个script标签
<script src="https://test329.suanshubang.com/Stats.php?callback=callback&date=20200715"></script>
跨域请求到test329上;
向php脚本传递了两个参数,一个是callback回调函数,用于取回数据;另一个是date参数,是传递给脚本的入参。

<!DOCTYPE html>
<html>
<head>
    <title>已分配任务的流转情况</title>
    <meta charset="utf-8">
    <script src="https://cdn.staticfile.org/echarts/4.7.0/echarts.min.js"></script>

    <div id="main" style="width: 900px;height:400px;"></div>
    <script>
        var g_data=[]
        function callback(data){

            console.log(data);
            g_data=data;

            var myChart = echarts.init(document.getElementById('main'));

            // 指定图表的配置项和数据

            option = {
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {            // 坐标轴指示器,坐标轴触发有效
                        type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
                    }
                },
                legend: {
                    data: g_data.legend
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                xAxis: [
                    {
                        type: 'category',
                        data: g_data.xAxis
                    }
                ],
                yAxis: [
                    {
                        type: 'value'
                    }
                ],
                series: g_data.series
            };


            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);
        }

    </script>


    <script language="javascript">

        function GetRequest() {
            var url = location.search; //获取url中"?"符后的字串
            var theRequest = new Object();
            if (url.indexOf("?") != -1) {
                var str = url.substr(1);
                strs = str.split("&");
                for(var i = 0; i < strs.length; i ++) {
                    theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);
                }
            }
            return theRequest;
        }

        var req = GetRequest();
        var req1 = JSON.stringify(req.date);

        const script = document.createElement('script');
        script.src = "https://test329.suanshubang.com/Stats.php?callback=callback&date=" + req1;
        script.async = false;
        document.head.appendChild(script);
    </script>
</head>
</html>

//Stats.php
$date = $_GET['date']; 获取入参date;
$params = $_GET['callback']; 获取回调函数;
echo $params . '(' . json_encode($output) . ')'; 调用回调函数,即可将后端数据outout传递给前端。

<?php

$date = $_GET['date'];
$date = substr($date, 1, 8);

Bd_Init::init('assistantcheck');
$stats  = new Stats();
$output = $stats->execute(['date' => $date]);

$params = $_GET['callback'];
echo $params . '(' . json_encode($output) . ')';

class Stats
{

    private $objCheckTaskMain = null;

    public function __construct()
    {
        $this->objCheckTaskMain = new Service_Data_Task_CheckTaskMain();
    }

    public function execute($input)
    {
        $targetDate = isset($input['date']) && intval($input['date']) != 0 ? intval($input['date']) : date('Ymd', time());
        $zeroTime   = strtotime($targetDate);

        $sql = "select item,check_status,count(*) as cnt from tblCheckTaskMain where delete_time =0 and  dispatch_time >= " . $zeroTime . " group by item,check_status";
        $ret = $this->objCheckTaskMain->query($sql);

        $item_status_cnt = [];
        foreach ($ret as $agg_data) {

            $key = $agg_data['item'] . '-' . $agg_data['check_status'];

            $item_status_cnt[$key] = $agg_data['cnt'];

        }

        $check_status_set = array_unique(array_column($ret, 'check_status'));
        sort($check_status_set);

        $legend = [];
        foreach ($check_status_set as $check_status) {
            $legend[$check_status] = Conf_Config::CHECK_STATUS_MAP[$check_status];
        }

        $xAxis = [3 => '订正', 4 => '上镜', 5 => '微信单聊', 6 => '微信群聊', 7 => '兼职辅审', 8 => '兼职纯批'];

        $series = [];

        foreach ($legend as $check_status => $check_status_name) {

            $tmp = [
                'name' => $check_status_name,
                'type' => 'bar',
                'data' => $this->getSeriesData($check_status, $xAxis, $item_status_cnt),
            ];

            $series[] = $tmp;
        }

        return [
            'legend' => array_values($legend),
            'xAxis'  => array_values($xAxis),
            'series' => array_values($series),
        ];


    }


    private function getSeriesData($check_status, $xAxis, $item_status_cnt)
    {

        $data = [];
        foreach ($xAxis as $item => $item_name) {
            $key    = $item . '-' . $check_status;
            $data[] = isset($item_status_cnt[$key]) ? intval($item_status_cnt[$key]) : 0;
        }
        return $data;
    }
}

过程中遇到的坑:
document.createElement('script');是动态生成一个script标签,追加到html中,这个script会最后执行。导致echart拿不到后端数据,渲染失败。

后来,将渲染echart的代码放到callback里函数执行,迎刃而解(前端小白两股瑟瑟)。

鸣谢: https://blog.csdn.net/weixin_43837229/article/details/90720536

相关文章

  • ajax跨域请求

    ajax跨域请求(jsonp) 利用JSONP解决AJAX跨域问题的原理与jQuery解决方案JSONP jQue...

  • JSONP跨域请求的小尝试

    众所周知,为了安全性考虑浏览器是不支持跨域请求的,哪些请求是跨域请求?什么是跨域请求总之,同源是指 协议、域名、端...

  • 跨域

    ??JSONP只能解决GET请求跨域,不能解决POST请求跨域问题,XHR2可以解决GET,POST方式的请求跨域...

  • 做demo和学习过程当中遇到的一些问题,收集的博文

    轻松搞定JSONP跨域请求--->关键字: 跨域, 同源策略, JSONP原理 git拉取远程分支到本地 git ...

  • tomcat 下web服务跨域访问

    因为项目中需要跨域访问文将上传服务器,尝试了jsonp的方式但是,只能跨域访问GET请求, 上传服务又是POST的...

  • JavaScript - GET/POST及跨域方法

    xhr 原生方法请求 window fetch 方法 关于跨域 利用JSONP实现跨域调用 使用 CORS(跨域资...

  • JSONP技术原理及实现

    转自《跨域jsonp的原理》 首先确定为什么要用jsonp,因为要跨域请求数据,那为什么会发生跨域呢,因为浏览器的...

  • js跨域问题

    来源 javascript中实现跨域的方式总结 第一种方式:jsonp请求;jsonp的原理是利用 标签的跨域特性...

  • javasscript - 收藏集 - 掘金

    jsonp 跨域请求详解——从繁至简 - 前端 - 掘金什么是jsonp?为什么要用jsonp?JSONP(JSO...

  • 跨域实战解决方案

    一.跨域方案 1.JSONP跨域 (1)前端发起jQuery ajax 的get请求 $.getJSON...

网友评论

      本文标题:JSONP跨域请求的小尝试

      本文链接:https://www.haomeiwen.com/subject/hdcghktx.html