【问题标题】:Is it valid to define functions in JSON results?在 JSON 结果中定义函数是否有效?
【发布时间】:2010-01-04 19:02:24
【问题描述】:

网站的部分 JSON 响应有这个(...为上下文添加):

{..., now:function(){return(new Date).getTime()}, ...}

向 JSON 添加匿名函数是否有效?我希望您每次访问“时间”时都会返回不同的值。

【问题讨论】:

  • 浏览器解析JSON成功了吗?如果是这样,那么它是有效的(在这方面)。
  • @harschware - 仅当 JSON 与 javascript 相关时才如此。作为一种语言无关的数据序列化格式,它是错误的,是一条有问题的路要走。
  • @jsoverson - 我同意。请参阅下面的答案。
  • 很容易自己回答这个问题:打开 web kit 检查器并运行:JSON.parse('{now:function(){return(new Date).getTime()}')。检查员说:Uncaught SyntaxError: Unexpected token n 快​​速浏览一下JSON spec 就证实了这一点。专注于“价值”部分。

标签: json anonymous-function


【解决方案1】:

没有。

JSON 纯粹是一种数据描述语言。如http://www.json.org 所述,它是一种“轻量级数据交换格式”。 - 不是编程语言。

根据http://en.wikipedia.org/wiki/JSON,支持的“基本类型”是:

  • 数字(整数、实数或浮点数 点)
  • 字符串(双引号 Unicode 反斜杠转义)
  • 布尔值 (真假)
  • 数组(一个有序的 值序列,逗号分隔 并用方括号括起来)
  • 对象(键的集合:值 对,逗号分隔和封闭 在花括号中)
  • null

【讨论】:

  • @Dr. Zim,不,将事物与 null 进行比较我所做的是 a==null?1:a.toString()=="" 它的作用是如果 a=null 则返回 1/true,如果它是 "" 表示空字符串,您也会得到 1/true..如果它不是 null 或“”,那么它将返回 0/false,您可以复制更多以使用 [] 和 {},只需将 ?1:a==[]?1:a.toString()=={}.toString(); 添加到我的 prev sn-p。所以也许这个功能会帮助你。 isnull=(function(a){return (a==null?1:a.toString()==""?1:a==[]?1:a.toString()=={}.toString())?true:false}) 我会使用 ?1:0 而不是 ?true:false 但是(真/假)
  • 同时,函数也是数据。
  • 我来到这里是在寻找一种使用 JSON 获取“更多数据”的方法。最好通知客户端(从服务器)如​​何获取更多数据,而不需要客户端担心接下来要调用哪个 REST 或其他 API。
  • @RavindranathAkila REST 暗示可能的下一个 API 调用在调用中公开。换句话说:您所做的 REST 请求会告诉您将来可能想要执行哪些请求(基于应用程序决策逻辑和数据)。一个完美的例子是 Github API,其中返回数据元素 - 但其中一些会导致其他 API 请求资源。
  • @Jens-AndréKoch 谢谢!会去看看
【解决方案2】:

问题在于 JSON 作为一种数据定义语言是从 JSON 作为一种 JavaScript 对象表示法演变而来的。由于 Javascript 支持 JSON 上的 eval,因此将 JSON 代码放入 JSON(在该用例中)是合法的。如果您使用 JSON 远程传递数据,那么我会说将方法放在 JSON 中是不好的做法,因为您可能没有很好地建模您的客户端-服务器交互。此外,当希望使用 JSON 作为数据描述语言时,我会说嵌入方法可能会给自己带来麻烦,因为一些 JSON 解析器在编写时只考虑了数据描述,可能不支持结构中的方法定义。

Wikipedia JSON entry 提供了一个很好的理由,即在 JSON 中不包含方法,理由是出于安全考虑:

除非您绝对信任文本的来源,并且您需要解析和接受不严格符合 JSON 的文本,否则您应该避免使用 eval() 并改用 JSON.parse() 或其他 JSON 特定的解析器。 JSON 解析器将仅识别 JSON 文本并拒绝其他可能包含恶意 JavaScript 的文本。在提供原生 JSON 支持的浏览器中,JSON 解析器也比 eval 快得多。预计原生 JSON 支持将包含在下一个 ECMAScript 标准中。

【讨论】:

  • 您可能在通俗地使用术语 JSON,但正式的“JSON”是一个 ECMA 标准,它不包含要编码的函数对象。当您说“JSON”时,您所指的功能应该没有歧义——这就是拥有标准的全部意义
  • 同意今天的情况。我没有引用来源,但我相信 JSON 是在 ECMA 进入 Javascript 游戏之前创造的一个术语,在 JSON 成为标准数据交换格式之前......因此我使用了“进化”这个术语
  • @harschware 根据 RFC 4627,JSON 是由 ECMA 生成的。
【解决方案3】:

让我们引用其中一个规范 - https://www.rfc-editor.org/rfc/rfc7159#section-12

JavaScript 对象表示法 (JSON) 数据交换格式规范 规定:

JSON 是 JavaScript 的子集,但不包括赋值和调用。

由于 JSON 的语法是从 JavaScript 借来的,因此可以 使用该语言的“eval()”函数来解析 JSON 文本。这 通常构成不可接受的安全风险,因为文本
可以包含可执行代码以及数据声明
。相同 考虑适用于在任何 JSON 文本符合的其他编程语言
语言的语法。

因此,所有不属于 JSON 标准的函数的状态都是正确的。

官方的回答是:不行,在JSON结果中定义函数是无效的!


答案可能是肯定的,因为“代码就是数据”和“数据就是代码”。 即使 JSON 被用作与语言无关的数据序列化格式,通过其他类型的“代码”隧道也将起作用。

可以使用 JSON 字符串将 JS 函数传递给客户端浏览器执行。

[{"data":[["1","2"],["3","4"]],"aFunction":"function(){return \"foo bar\";}"}]

这会导致类似的问题:如何“https://stackoverflow.com/questions/939326/execute-javascript-code-stored-as-a-string”。

做好准备,举起你的“eval() 是邪恶的”标志,并在它旁边贴上你的“不要通过 JSON 隧道函数”标志。

【讨论】:

    【解决方案4】:

    据我所知,这不是标准的。快速查看http://json.org/ 即可确认这一点。

    【讨论】:

      【解决方案5】:

      JSON 明确排除函数,因为它并不意味着是纯 JavaScript 数据 结构(尽管名称中有 JS)。

      【讨论】:

        【解决方案6】:

        不,绝对不是。

        如果你使用一个不错的 JSON 序列化器,它不会让你序列化这样的函数。这是一个有效的 OBJECT,但不是有效的 JSON。无论该网站的意图是什么,它都不会发送有效的 JSON。

        【讨论】:

        • 我使用 JSON-Lib 并认为它是一个很棒的序列化器。从 [使用页面](json-lib.sourceforge.net/usage.html) 你可以看到它可以很好地序列化函数
        • 有趣...我以前从未见过。这绝对不是规范(json.org 明确指出 JSON 是独立于语言的,而函数定义不是),但仍然很有趣。
        • 有趣的是,它应该是独立于语言的,但 JSON 代表 JavaScript Object Notation 嗯,很奇怪..
        【解决方案7】:

        简短的回答是...

        JSON 是一种完全独立于语言的文本格式,但使用 C 系列程序员熟悉的约定 语言,包括 C、C++、C#、Java、JavaScript、Perl、Python 和 很多其他的。这些属性使 JSON 成为理想的数据交换 语言。

        看看原因:

        在浏览器和服务器之间交换数据时,数据只能 是文本。

        JSON 是文本,我们可以将任何 JavaScript 对象转换为 JSON,并且 将 JSON 发送到服务器。

        我们还可以将从服务器接收到的任何 JSON 转换为 JavaScript 对象。

        通过这种方式,我们可以将数据作为 JavaScript 对象来处理,而无需 复杂的解析和翻译。

        但是等待...

        仍有存储函数的方法,广泛不推荐这样做,但仍有可能:

        我们说过,你可以保存一个string...那么将你的函数转换为字符串怎么样?

        const data = {func: '()=>"a FUNC"'};
        

        然后您可以使用JSON.stringify(data) 对数据进行字符串化,然后使用JSON.parse 对其进行解析(如果需要此步骤)...

        eval 来执行一个字符串函数(在此之前,请让您知道广泛不推荐使用 eval):

        eval(data.func)(); //return "a FUNC"
        

        【讨论】:

          【解决方案8】:

          通过使用 NodeJS(commonJS 语法),我能够使这种类型的功能正常工作,我最初在一些外部 JS 文件中只有一个 JSON 结构,但我希望该结构更像是一个类,其方法可以在运行时决定。

          不需要在 myJSON 中声明 'Executor'。

          var myJSON = {
              "Hello": "World",
              "Executor": ""
          }
          
          module.exports = {
              init: () => { return { ...myJSON, "Executor": (first, last) => { return first + last } } }
          }
          

          【讨论】:

            【解决方案9】:

            JSON 中的函数表达式是完全可以的,只是不要忘记用双引号括起来。下面是一个取自 noSQL 数据库设计的示例:

            {
              "_id": "_design/testdb",
              "views": {
                "byName": {
                  "map": "function(doc){if(doc.name){emit(doc.name,doc.code)}}"
                }
              }
            }
            

            【讨论】:

            • 问题是关于函数而不是字符串。 JSON 支持字符串值,但不支持函数。详情见Mike's answer
            • @jannis 是可能的。如果你添加一个自调用函数,比如。这里的人显然只是不知道答案。
            【解决方案10】:

            虽然不推荐使用 eval,但这是可行的:

            <!DOCTYPE html>
            <html>
            <body>
            
            <h2>Convert a string written in JSON format, into a JavaScript function.</h2>
            
            <p id="demo"></p>
            
            <script>
                function test(val){return val + " it's OK;}
                var someVar = "yup";
                var myObj = { "func": "test(someVar);" };
                document.getElementById("demo").innerHTML = eval(myObj.func);
            </script>
            
            </body>
            </html>
            

            【讨论】:

            • 投了反对票,因为在示例中不需要使用 HTML,这是 5 年前的编码风格,缺少引号,并且 JSON 文件不应该包含函数,如果它们包含它们不能被序列化,也不能存储在无 sql 数据库中,
            【解决方案11】:

            把引号去掉...

            var a = {"b":function(){alert('hello world');} };
            
            a.b();
            

            【讨论】:

            • 这是 JavaScript,问题是关于 JSON。
            猜你喜欢
            • 1970-01-01
            • 2012-06-14
            • 1970-01-01
            • 2012-09-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-15
            • 2016-04-19
            相关资源
            最近更新 更多