103

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

{..., 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.

Zachary Scott
  • 20,968
  • 35
  • 123
  • 205
  • Did the JSON parse successfully by the browser? If so then yes it is valid (in that respect). – harschware Jan 04 '10 at 19:36
  • 7
    @harschware - that is true only as JSON relates to javascript. As a language independent data serialization format it is false and is a problematic road to walk down. – jsoverson Jan 04 '10 at 19:40
  • @jsoverson - I agree. See my answer below. – harschware Jan 04 '10 at 19:46
  • 1
    Easy to answer this question yourself: open up web kit inspector and run: `JSON.parse('{now:function(){return(new Date).getTime()}')`. The inspector says: `Uncaught SyntaxError: Unexpected token n` A quick glance at the [JSON spec](http://www.json.org/) confirms this. Focus on the 'value' section. – Mark E. Haase Jan 31 '15 at 14:05

11 Answers11

107

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.

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

  • 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
Community
  • 1
  • 1
Mike
  • 23,892
  • 18
  • 70
  • 90
  • Is [], {} equal to null? I know nothing is comparable to null, including null, but is an empty set evaluated as a null value? – Zachary Scott Oct 30 '10 at 21:06
  • 2
    @Dr. Zim, no and to compare things to null what i do is this `a==null?1:a.toString()==""` What this does is it says if a=null then it returns 1/true, if it is "" meaning empty string you also get 1/true.. if it is not null or "" then it will return 0/false, you can replicate this more to work with [] and {} simply just be adding `?1:a==[]?1:a.toString()=={}.toString();` to my prev snippet. so maybe this function will help you. `isnull=(function(a){return (a==null?1:a.toString()==""?1:a==[]?1:a.toString()=={}.toString())?true:false})` I would use `?1:0` instead of `?true:false` but (true/false) – JamesM-SiteGen Jan 04 '11 at 06:05
  • 14
    At the same time, functions are data too. – argyle Mar 01 '12 at 18:55
  • 2
    I landed here while finding a way to fetch "further data" using JSON. It would be nice to inform a client (from the server) how to get further data, without the client worrying about which REST or so api to call next. – Ravindranath Akila Jun 24 '14 at 07:48
  • 3
    @RavindranathAkila REST implies that possible next API calls are exposed in the call. In other words: the REST request you did, tells you which future requests, you might want to do (based on the application decision logic and the data). A perfect example for this is the Github API, where data elements are returned - but some of them lead to other API request resources. – Jens A. Koch Jan 05 '15 at 12:34
  • no sorry, you CAN declare a function in JSON, and you don't even need the "function" keyword var whatever = {log(avalue){console.log(avalue)}}.log('hello') 80 people liked this answer ? JSON can contain ANY javascript object – Martijn Scheffer Mar 17 '17 at 18:51
  • (of course if, by JSON, you mean the text returned by a server, ok yes than u can't include code, but THAT is not JSON, json is any javascript litteral. – Martijn Scheffer Mar 17 '17 at 19:00
16

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.

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

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.

harschware
  • 13,006
  • 17
  • 55
  • 87
  • 2
    You may be using the term JSON colloquially, but officially "JSON" is an ECMA standard that does not bare function objects to be encoded. There should be no ambiguity which capabilities you are referring to when you say "JSON" — that's the _whole point_ of having a standard. – Mark E. Haase Jan 31 '15 at 14:09
  • Agreed that is true today. I don't have a source to cite, but I believe JSON was a term coined before ECMA came into the Javascript game, and before JSON was a standard data exchange format... hence I used the term 'evolved' – harschware Feb 02 '15 at 21:59
  • @harschware According to RFC 4627, JSON was made from ECMA. – Jenna Sloan May 01 '19 at 03:57
11

Let's quote one of the spec's - https://www.rfc-editor.org/rfc/rfc7159#section-12

The The JavaScript Object Notation (JSON) Data Interchange Format Specification states:

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.

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

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


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.

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

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

This leads to question's like: How to "https://stackoverflow.com/questions/939326/execute-javascript-code-stored-as-a-string".

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

Community
  • 1
  • 1
Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
8

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

jldupont
  • 93,734
  • 56
  • 203
  • 318
5

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.

Jerod Venema
  • 44,124
  • 5
  • 66
  • 109
  • 2
    I use JSON-Lib and consider it to be a great serializer. From the [usage page](json-lib.sourceforge.net/usage.html) you can see it will serialize functions just fine – harschware Jan 04 '10 at 21:54
  • Interesting...I've never seen that before. It's definitely not to spec (http://www.json.org/ explicitly states that JSON is language independent, which function definitions are not), but interesting nonetheless. – Jerod Venema Jan 05 '10 at 02:30
  • 1
    It's funny that it's supposed to be language independent but JSON stands for JavaScript Object Notation hmm weird.. – Nate-Wilkins Oct 18 '13 at 15:15
4

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

Tatu Ulmanen
  • 123,288
  • 34
  • 187
  • 185
4

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.

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.

But wait...

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

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

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

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

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

eval(data.func)(); //return "a FUNC"
Alireza
  • 100,211
  • 27
  • 269
  • 172
0

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.

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

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

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

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:

{
  "_id": "_design/testdb",
  "views": {
    "byName": {
      "map": "function(doc){if(doc.name){emit(doc.name,doc.code)}}"
    }
  }
}
np_6
  • 514
  • 1
  • 6
  • 19
  • The question is about a function not a string. JSON supports string values, but it doesn't support functions. See [Mike's answer](https://stackoverflow.com/a/2001471/4494577) for details – jannis Sep 07 '17 at 08:29
  • @jannis its possible though. if you add a self invoking function like. people here apparently just dont know the answer. – Rogelio Nov 22 '19 at 11:34
-6

although eval is not recommended, this works:

<!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>
pascati
  • 9
  • 2
  • 1
    voted down because its not neccesary to use HTML in the example, this is 5 year old coding style, there is a missing quote, and, JSON files aren't supposed to contain functions, if they do they cannot be serialised, or stored in a no sql DB, – Martijn Scheffer Nov 06 '19 at 16:26
-7

Leave the quotes off...

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

a.b();
John Slegers
  • 45,213
  • 22
  • 199
  • 169