为啥将数据从 php 发送到 javascript (Laravel) 时进行 json 编码?

Posted

技术标签:

【中文标题】为啥将数据从 php 发送到 javascript (Laravel) 时进行 json 编码?【英文标题】:Why json encode when sending data from php to javascript (Laravel)?为什么将数据从 php 发送到 javascript (Laravel) 时进行 json 编码? 【发布时间】:2017-05-31 14:01:02 【问题描述】:

我刚刚阅读了this 问题,并注意到很多显示 json 编码的答案。我只是想知道为什么?是为了某种安全吗?因此,例如在 Laravel 中,这是否是正确的方法来拉取东西

var date = '!! json_encode($event->date) !!',
parseDate = JSON.parse(date);

//use parseDate here.

很抱歉提出一个全新的问题,但我没有代表对原始问题发表评论:/

【问题讨论】:

您的问题似乎与您发布的链接没有任何关系,除了引用 laravel 和一些 json 函数。您链接中的人询问如何在 javascript 中发送和访问 Eloquent 实例,一个简单、重要的方法是对其属性进行 json_encode 并将其传递给 javascript。 @georaldc 他的问题是为什么有必要对所述数据进行 json_encode。 :) 这是因为javascript变量存储为json 【参考方案1】:

我只是在通过“使用 oauth 登录”回调刀片模板将数据从 Laravel API 发送到 Vue SPA 时遇到了这个问题。

我花了一些时间才弄清楚如何修复有效载荷。感谢Amit Gupta的回答,我在这个问题中找到了答案。

这是退出 Laravel 的有效负载,用于上下文:

    return view('oauth/callback', [
        'user' => $user,
    ]);

然后,在callback.blade.php,我有这个代码:

<html>
    <head>
        <meta charset="utf-8">
        <title> config('app.name') </title>
        <script>
            window.opener.postMessage(
                
                    user: !! $user !!,
                ,
                " url('/') "
            );

            window.close();
        </script>
    </head>

    <body>
    </body>

</html>

我不得不改变这个:

user: " $user ",

到这里:

user: !! $user !!,

在修复之前,我将一个字符串化对象插入到字符串中,所以我被SyntaxError: Unexpected token o in JSON at position 1 错误所困扰,因为 字符没有用双引号括起来。

这是我接收有效负载的 JavaScript:

    onMessage(e) 
        const hasUser = (e.data.user && (Object.keys(e.data.user).length > 0));

        if ((e.origin !== window.origin) || !hasUser) 
            return undefined;
        

        console.log('user payload', e.data.user);
        console.log('type', typeof e.data.user);

        if (this.hasIntendedUrl) 
            return this.$router.push(this.$store.getters['auth/intendedUrl'])
                .then(() => this.$store.dispatch('auth/clearIntendedUrl'))
                .catch(() => );
        

        return this.$router.push( name: 'home' ).catch(() => );
    ,

您可以看到我不需要JSON.parse(),因为typeof e.data.userobject

很抱歉,这里的答案很长,但我想展示一个完全合格的解决方案。对我来说,这只是一个类型转换问题,首先基于 JSON 对负载进行字符串化,然后进行 JSON 解析。这意味着 Laravel 应该专注于准备对象的传输安全版本,而 JavaScript 应该专注于将其转换回 Object。

在同一个文件中混合 PHP 和 JS 总是一个棘手的问题。正如您在我的示例中看到的那样,那些无害的 " 包装 " $user " 是 JavaScript 代码被指示将对象放入字符串中,而这不能是 JSON.parse()'d。

【讨论】:

【参考方案2】:

作为对 Amit Gupa 的回应,这里是没有解析就无法工作的代码(基于 this)。好的,第一部分是视图的主要部分。 $event 是从数据库中提取的,日期和时间是分开存储的。我使用 laravel widgets 将其用作小部件,尽管它几乎可以用作普通视图。

<div id="clockdiv">
        <div class = 'timeFormat form-group-shadow'>
            <span class="days">0</span>
            <div class="small-text">Days</div>
        </div>
        <div class = 'timeFormat form-group-shadow'>
            <span class="hours">00</span>
            <div class="small-text">Hours</div>
        </div>
        <div class = 'timeFormat form-group-shadow'>
            <span class="minutes">00</span>
            <div class="small-text">Minutes</div>
        </div>
        <div class = 'timeFormat form-group-shadow'>
            <span class="seconds">00</span>
            <div class="small-text">Seconds</div>
        </div>
    </div>
</div>

 HTML::script('js/countdown.js') 

<script>
    var date = '@if(isset($event))!! json_encode($event->date) !!@endif',
    time = '@if(isset($event))!! json_encode($event->time) !!@endif',
    dateTime = JSON.parse(date) + " " + JSON.parse(time);

   if(new Date(dateTime) >= Date.now())
       initializeClock('clockdiv', dateTime);
   ;
</script>

脚本'js/countdown.js'可以在这里看到。

function getTimeRemaining(endtime)
    var t = Date.parse(endtime) - Date.parse(new Date());
    var seconds = Math.floor( (t/1000) % 60 );
    var minutes = Math.floor( (t/1000/60) % 60 );
    var hours = Math.floor( (t/(1000*60*60)) % 24 );
    var days = Math.floor( t/(1000*60*60*24) );
    return 
        'total': t,
        'days': days,
        'hours': hours,
        'minutes': minutes,
        'seconds': seconds
    ;


function initializeClock(id, endtime)
    var clock = document.getElementById(id);
    var daysSpan = clock.querySelector('.days');
    var hoursSpan = clock.querySelector('.hours');
    var minutesSpan = clock.querySelector('.minutes');
    var secondsSpan = clock.querySelector('.seconds');

    function updateClock()
        var t = getTimeRemaining(endtime);
        daysSpan.innerHTML = t.days;
        hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
        minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
        secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
        if(t.total<=0)
            clearInterval(timeinterval);
        
    

     updateClock();

     var timeinterval = setInterval(updateClock,1000);

这段代码运行良好,但当我不解析时失败。

【讨论】:

如果你在 Javascript 中使用JSON.parse('2017-01-25'),那么它将失败。当你在做json_encode时,你不需要JSON.parse$.parseJSON【参考方案3】:

当您将json_encode 用作:

var date = !! json_encode($event->date) !!;

然后它返回一个JSON 字符串。 PHP json_encode 函数将传递给它的数据转换为 JSON 字符串,然后可以将其输出到 JavaScript 变量。 JSON 是 JavaScript 文字符号的子集,因此您可以将 JSON 直接放入 JavaScript 代码中,只要表达式有效。

不需要JSON.parse$.parseJSON,事实上,使用它们会失败。

date 要么是 JavaScript 对象(如果 PHP“关联”数组有非数字键,所以 json_encode 输出 ...)或 JavaScript 数组(如果 json_encode 输出 [...])。

【讨论】:

我做了一个小倒计时应用程序,如果不先执行 JSON.parse,它将无法工作。嗯,也许我做错了。 添加为另一个答案。【参考方案4】:

一般来说,当您想要保留其结构时,JSON 用于将数据从服务器发送到浏览器。在 Javascript 中很容易解析,结果是一个与服务器语言(如 PHP)中的原始数组匹配的数组。对于简单的单一值,它并不是真正需要的。

【讨论】:

以上是关于为啥将数据从 php 发送到 javascript (Laravel) 时进行 json 编码?的主要内容,如果未能解决你的问题,请参考以下文章

将数据从 javascript 发送到 html 并使用 php 获取

将数据从 javascript forEach 循环中的 php 数组发送到 ajax 调用的 url

通过 XMLHttpRequest 从 JavaScript 向 PHP 发送数据

为啥在使用 AJAX/PHP 时收到未定义索引错误?

将PHP变量发送到javascript函数[重复]

使用 PHP 获取 SQL 数据,然后将数组发送到 Javascript