在 JSON 结果中定义函数是否有效?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2001449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:23:08  来源:igfitidea点击:

Is it valid to define functions in JSON results?

jsonanonymous-function

提问by Zachary Scott

Part of a website's JSON response had this (... added for context):

网站的 JSON 响应的一部分具有以下内容(...为上下文添加):

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

Is adding anonymous functions to JSON valid? I would expect each time you access 'time' to return a different value.

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

回答by Mike

No.

不。

JSON is purely meant to be a data description language. As noted on http://www.json.org, it is a "lightweight data-interchange format." - not a programming language.

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

Per http://en.wikipedia.org/wiki/JSON, the "basic types" supported are:

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

  • Number (integer, real, or floating point)
  • String (double-quoted Unicode with backslash escaping)
  • Boolean (true and false)
  • Array (an ordered sequence of values, comma-separated and enclosed in square brackets)
  • Object (collection of key:value pairs, comma-separated and enclosed in curly braces)
  • null
  • 数字(整数、实数或浮点数)
  • 字符串(带反斜杠转义的双引号 Unicode)
  • 布尔值(真和假)
  • 数组(有序的值序列,以逗号分隔并括在方括号中)
  • 对象(键值对的集合,逗号分隔并括在花括号中)
  • null

回答by harschware

The problem is that JSON as a data definition language evolved out of JSON as a JavaScript Object Notation. Since Javascript supports eval on JSON, it is legitimate to put JSON code inside JSON (in that use-case). If you're using JSON to pass data remotely, then I would say it is bad practice to put methods in the JSON because you may not have modeled your client-server interaction well. And, further, when wishing to use JSON as a data description language I would say you could get yourself into trouble by embedding methods because some JSON parsers were written with only data description in mind and may not support method definitions in the structure.

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

Wikipedia JSON entrymakes a good case for not including methods in JSON, citing security concerns:

维基百科 JSON 条目很好地说明了不包括 JSON 中的方法,引用了安全问题:

Unless you absolutely trust the source of the text, and you have a need to parse and accept text that is not strictly JSON compliant, you should avoid eval() and use JSON.parse() or another JSON specific parser instead. A JSON parser will recognize only JSON text and will reject other text, which could contain malevolent JavaScript. In browsers that provide native JSON support, JSON parsers are also much faster than eval. It is expected that native JSON support will be included in the next ECMAScript standard.

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

回答by Jens A. Koch

Let's quote one of the spec's - http://tools.ietf.org/html/rfc7159#section-12

让我们引用规范之一 - http://tools.ietf.org/html/rfc7159#section-12

The The JavaScript Object Notation (JSON) Data Interchange Format Specificationstates:

所述的JavaScript对象符号(JSON)数据交换格式规范规定:

JSON is a subset of JavaScript but excludes assignment and invocation.

Since JSON's syntax is borrowed from JavaScript, it is possible to use that language's "eval()" function to parse JSON texts. This generally constitutes an unacceptable security risk, since the text
could contain executable code along with data declarations
. The same consideration applies to the use of eval()-like functions in any other programming language in which JSON texts conform to that
language's syntax.

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

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

So all answers which state, that functions are not part of the JSON standard are correct.

因此,所有声明函数不属于 JSON 标准的答案都是正确的。

The official answer is: No, it is not valid to define functions in JSON results!

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



The answer could be yes, because "code is data" and "data is code". Even if JSON is used as a language independent data serialization format, a tunneling of "code" through other types will work.

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

A JSON string might be used to pass a JS function to the client-side browser for execution.

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

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

This leads to question's like: How to "Execute JavaScript code stored as a string".

这导致了类似的问题:如何“执行存储为字符串的 JavaScript 代码”。

Be prepared, to raise your "eval() is evil" flag and stick your "do not tunnel functions through JSON" flag next to it.

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

回答by jldupont

It is not standard as far as I know. A quick look at http://json.org/confirms this.

据我所知,这不是标准的。快速浏览一下http://json.org/证实了这一点。

回答by jvenema

Nope, definitely not.

不,绝对不是。

If you use a decent JSON serializer, it won't let you serialize a function like that. It's a valid OBJECT, but not valid JSON. Whatever that website's intent, it's not sending valid JSON.

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

回答by Tatu Ulmanen

JSON explicitly excludes functions because it isn't meant to be a JavaScript-only data structure (despite the JS in the name).

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

回答by Alireza

A short answer is NO...

简短的回答是否定的...

JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

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

Look at the reason why:

看看原因:

When exchanging data between a browser and a server, the data can only be text.

JSON is text, and we can convert any JavaScript object into JSON, and send JSON to the server.

We can also convert any JSON received from the server into JavaScript objects.

This way we can work with the data as JavaScript objects, with no complicated parsing and translations.

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

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

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

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

But wait...

但是等等...

There is still ways to store your function, it's widely not recommendedto that, but still possible:

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

We said, you can save a string... how about converting your function to a string then?

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

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

Then you can stringify data using JSON.stringify(data)and then using JSON.parseto parse it (if this step needed)...

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

And evalto execute a string function (before doing that, just let you know using eval widely not recommended):

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

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

回答by Mitchell Spangler

Via using NodeJS (commonJS syntax) I was able to get this type of functionality working, I originally had just a JSON structure inside some external JS file, but I wanted that structure to be more of a Class, with methods that could be decided at run time.

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

The declaration of 'Executor' in myJSON is not required.

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

var myJSON = {
    "Hello": "World",
    "Executor": ""
}

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

回答by Eimantas P?likis

Function expressions in the JSON are completely possible, just do not forget to wrap it in double quotes. Here is an example taken from noSQL database design:

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

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

回答by pascati

although eval is not recommended, this works:

虽然不推荐使用 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>