[31] [DFN[[RUBY[[[JSON]]][ジェイソン]]]] ([DFN[JavaScript Object Notation]] / [DFN[JavaScript オブジェクト記法]]) は、 [[JavaScript]] における[[オブジェクト・リテラル]]の[[部分集合]]によって[[オブジェクト]]や[[配列]]を表記するデータ交換書式です。 [[JavaScript]] を始め数多くの[[言語]]で[[ライブラリー]]が整備されており、 汎用的な[[データ構造]]の交換形式として広く用いられています。 [30] [CITE@en[JSON]] ([TIME[2011-07-09 12:55:13 +09:00]] 版) >JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. 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. * 仕様書 - [3] [CITE@en[RFC 4627 - The application/json Media Type for JavaScript Object Notation (JSON)]] - [34] [CITE[Annotated ES5]] -- [35] [CSECTION@en[5.1.5 The JSON Grammar]] -- [36] '''[CSECTION@en[15.12 The JSON Object]] ''' [104] [[ES5]] は、 [[RFC]] を引用しつつも独自に構文や解釈を規定しています。 * データ型 [37] [[JSON]] では以下の[[データ型]]を表現できます [SRC[>>3 1.]]。 - [38] [RUBYB[[[プリミティブ型]]]@en[primitive types]] -- [39] [RUBYB[[[文字列]]]@en[string]] -- [40] [RUBYB[[[数値]]]@en[number]] -- [41] [[boolean]] -- [42] [[null]] - [43] [RUBYB[[[構造化型]]]@en[structured types]] -- [44] [RUBYB[[[オブジェクト]]]@en[object]] -- [45] [RUBYB[[[配列]]]@en[array]] * 構文 ** 文字符号化 [69] [[JSONテキスト]]は [[Unicode]] で[[符号化]]しなければ[['''なりません''']] [SRC[>>3 3.]]。 [70] [[Unicode]] のどの[[符号化方式]]、というような限定はされていません。 どれを使っても良いということでしょうか。 [[UTF-8]]、[[UTF-16]]、[[UTF-32]] を使って構わないという記述はありますが [SRC[>>3 6.]]、 それ以外を使ってはいけないとは明確に規定されていません。 [71] [[既定]]の[[符号化]]は [[UTF-8]] です [SRC[>>3 3.]]。しかしこの「既定」 が何を表すのかは明記されていません。特に意図がなければ [[UTF-8]] を使うべきであるということでしょうか。あるいは[[文字符号化方式]]が特定できないときに [[UTF-8]] として解釈するべきということでしょうか。 [75] 実装はこれらの[[符号化方式]]のいずれ、あるいはすべてに対応しなければならないのか、 しなくてもよいのか、といったことは規定されていません。 *** Sniffing [72] [[RFC]] の規定する [[JSONテキスト]]は、最初の2文字が必ず [[ASCII文字]]となります。 そのため、最初の4つの[[オクテット]]のパターンにより、 ,[CODE[00 00 00 [VAR[xx]]]],[[UTF-32BE]] ,[CODE[00 [VAR[xx]] 00 [VAR[xx]]]],[[UTF-16BE]] ,[CODE[[VAR[xx]] 00 00 00]],[[UTF-32LE]] ,[CODE[[VAR[xx]] 00 [VAR[xx]] 00]],[[UTF-16LE]] ,[CODE[[VAR[xx]] [VAR[xx]] [VAR[xx]] [VAR[xx]]]],[[UTF-8]] ... と区別できるとされています。 [SRC[>>3 3.]] [VAR[xx]] は [CODE[00]] 以外の[[オクテット]]を表すのでしょう。 [[JSONテキスト]]に直接 [CODE(char)[[[U+0000]]]] が出現することは無いとされているので、 [CODE[00]] かどうかで確実に判定できます。 [73] [[ES5]] によって拡張された [[JSON]] として解釈される[[文字列]]は、 2文字目が必ずしも [[ASCII文字]]であるとは限りません ([[文字列リテラル]]の場合。) が、 それでもやはり同様にこれら5つの[[文字符号化方式]]を区別できます。 [74] [[RFC]] は [[BOM]] について言及していません。 [[BOM]] がある場合はこのパターンに当てはまらず、 [[UTF-16]] や [[UTF-32]] であっても [[UTF-8]] と判定されてしまいます。ただし [[RFC]] のこの部分は単なる事実の記述であって、そう解釈[[しなければならない]]などと規定されているわけではなく、 また明確に [[BOM]] を使用しては[[ならない]]と規定されているわけでもありませんから、 どう理解するべきか難しいところです。 [76] この [[sniffing]] は、実装が必ず使わなければならないなどという規定は特にありません。 しかし [CODE(MIME)@en[[[application/json]]]] には [CODE(MIME)@en[[[charset]]]] [[引数]]がありませんし、実際にこれらの[[文字符号化]]が使われているのであれば、 これ、あるいはこれに類する [[sniffing]] を実装する以外に選択肢はありません。 ** 字句解析 [46] [[JSONテキスト]]は、次の[[字句]]により構成されます [SRC[>>3 2.]]。 - [RUBYB[構造的文字]@en[structual character]] -- [CODE(char)[[['''[''']]]], [CODE(char)[[[''']''']]]], [CODE(char)[[[{]]]], [CODE(char)[[[}]]]], [CODE(char)[[[:]]]], [CODE(char)[[[,]]]] -- 前後に[[空白]]があっても構いません。 -- [[空白]]は、0[[文字]][[以上]]の [CODE(char)[[[U+0009]]]], [CODE(char)[[[U+000A]]]], [CODE(char)[[[U+000D]]]], [CODE(char)[[[U+0020]]]] です。 - JSON [RUBYB[値]@en[value]] -- [[文字列]] -- [[数値]] -- [[リテラル名]] --- [CODE(char)[[[true]]]], [CODE(char)[[[false]]]], [CODE(char)[[[null]]]] --- [[小文字]]でなければ[['''なりません''']]。 [100] [[RFC]] の [[JSON]] は、 [[ABNF]] により [[Unicode]] [[文字]]について定義されています [SRC[>>3]]。 [[ES5]] の [[JSON]] は、 [[BNF]] により [[SourceCharacter]]、すなわち [[UTF-16]] の[[16ビット符号単位]]について定義されています [SRC[>>36 15.12]]。実質的には同じです。 ** 構文 [47] [[RFC]] により規定される [DFN[JSON [RUBYB[テキスト]@en[text]]]]は、 [[オブジェクト]]または[[配列]]を1つ[[直列化]]したものです [SRC[>>3 2.]]。 [101] [[ES5]] により規定される [CODE[[[JSONText]]]] は、それに加えて他の[[文字列]]や[[数値]]や [[true]] や [[false]] や [[null]] のような値も認めています [SRC[>>36 15.12]]。 *** オブジェクト [48] [[オブジェクト]]は、 [CODE(char)[[['''{''']]]] の後に0個[[以上]]の[RUBYB[[[メンバー]]]@en[member]]を [CODE(char)[[[,]]]] で区切って並べ、最後に [CODE(char)[[['''}''']]]] が来る文字列として表されます。 メンバーは、名前と値の組であり、[[文字列]]の後に [CODE(char)[[[:]]]] が来て、 その後に値が来ます。 [SRC[>>3 2.2.]] [49] [[オブジェクト]]内で名前は固有である[['''べきです''']] [SRC[>>3 2.2.]]。 [52] 最後の[[メンバー]]の後に [CODE(char)[[[,]]]] を入れることは認められていません。 *** 配列 [50] [[配列]]は、 [CODE(char)[[['''[''']]]] の後に0個[[以上]]の値を [CODE(char)[[[,]]]] で区切って並べ、最後に [CODE(char)[[[''']''']]]] が来る文字列として表されます。 [SRC[>>3 2.3.]] [51] 最後の値の次に [CODE(char)[[[,]]]] を入れることは認められていません。 *** 数値 [53] [[数値]]は、必要なら[[負符号]]の後、[[整数部]]が来て、 必要なら[[小数部]]が来て、最後に必要なら[[指数部]]が来る形を取ります。 [SRC[>>3 2.4.]] - number = ["-"] int ["." 1*DIGIT] [ exp ] - int = "0" / ( (DIGIT - "0") *DIGIT ) - exp = "e" ["-" / "+"] 1*DIGIT [54] 先頭に[[正符号]]を使うことは認められていません。 ([[指数部]]では使えます。) [55] [[十進数]]により表記します。 [56] [[整数部]]で[[先導0]]は認められていません。 [57] [[無限大]]や[[NaN]]は表現できません。 [SRC[>>3 2.4.]] *** 文字列 [58] [[文字列]]は、0個以上の[[文字]]を[[引用符]]で括ることによって表されます。 [SRC[>>3 2.5.]] [59] [[文字]]は [[escape]] により表現することができます。特に[[引用符]]、 [CODE(char)[[[\]]]], [CODE(char)[[[U+0000]]]] - [CODE(char)[[[U+001F]]]] については必ず [[escape]] しなければなりません。 [SRC[>>3 2.5.]] [65] ,[CODE(JS)[\"]],[CODE(char)[[["]]]] ,[CODE(JS)[\\]],[CODE(char)[[[\]]]] ,[CODE(JS)[\/]],[CODE(char)[[[/]]]] ,[CODE(JS)[\b]],[CODE(char)[[[U+0008]]]] ,[CODE(JS)[\f]],[CODE(char)[[[U+000C]]]] ,[CODE(JS)[\n]],[CODE(char)[[[U+000A]]]] ,[CODE(JS)[\r]],[CODE(char)[[[U+000D]]]] ,[CODE(JS)[\t]],[CODE(char)[[[U+0009]]]] ,[CODE(JS)[\u[VAR[HHHH]]]],[CODE(char)[U+[VAR[HHHH]]]] ;; [66] [[大文字]]と[[小文字]]は区別されます。しかし[[十六進数]]は[[大文字]]でも[[小文字]]でも構いません。 [SRC[>>3 2.5.]] [60] [CODE(char)[[[U+10000]]]] [[以上]]の[[文字]]は [[UTF-16]] [[サロゲート・ペア]]の2つの[[16ビット符号単位]]の列によって [[escape]] で表せます。 [SRC[>>3 2.5.]] [64] [[RFC]] の [[ABNF]] 上は [[Unicode]] の[[サロゲート・ペア]]や[[非文字]]の[[符号位置]]を使うことは明確に禁止されていません。 [61] 明記されていませんが、半分は[[サロゲート・ペア]]の[[符号位置]]そのまま、 もう半分は [[escape]] というような列で [CODE(char)[[[U+10000]]]] より大きな[[文字]]を表現することは認められていないとも解釈できます。 *** boolean [67] [CODE(JS)[[[true]]]] や [CODE(JS)[[[false]]]] は、それぞれ [[boolean]] の[[真]]と[[偽]]を表します。これらは[[小文字]]でなければなりません。 *** null [68] [CODE(JS)[[[null]]]] は、 [[null]] を表します。これは[[小文字]]でなければなりません。 * 構文解析器 [77] [DFN[JSON [RUBYB[構文解析器]@en[parser]]]]は、 [[JSONテキスト]]を他の表現に変形するものです [SRC[>>3 4.]]。 [78] [[JSON構文解析器]]は、 [[JSON]] の文法に適合するすべての[[テキスト]]を[[受理]]しなければ[['''なりません''']] [SRC[>>3 4.]]。 [79] [[JSON構文解析器]]は、 [[JSON]] ではない形式や拡張を[[受理]]しても[['''構いません''']] [SRC[>>3 4.]]。 [80] [[受理]]する[[テキスト]]の[[サイズ]]を制限して構いません [SRC[>>3 4.]]。 [81] [[入れ子]]の深さを制限して構いません [SRC[>>3 4.]]。 [82] [[数値]]の範囲を制限して構いません [SRC[>>3 4.]]。 [83] [[文字列]]の[[長さ]]や[[文字]]の[[内容]]を制限して構いません [SRC[>>3 4.]]。 ;; [84] これらの制限に抵触する場合にどのように処理しなければならないかは規定されていません。 また、 >>83 の文字の内容の制限というのが具体的に何を指しているかは不明確です。 特定の種類の文字から構成される文字列以外を処理できなくても構わないといったことでしょうか。 [102] [[ES5]] の [CODE(JS)[[[JSON.parse]]]] は、 >>79 の拡張は認めておらず、 [[ES5]] の規定に厳密に従って構文解析しなければなりません [SRC[>>36 15.12]]。 なお、 [[ES5]] の規定は [[RFC]] の規定より若干拡張されています (>>101)。 * 生成器 [85] [DFN[JSON [RUBYB[生成器]@en[generator]]]]は、 [[JSONテキスト]]を生産するものです [SRC[>>3 5.]]。 [86] [[JSON生成器]]が生産する[[テキスト]]は、[[JSON]] の[[文法]]に厳密に[[適合]]しなければ[['''なりません''']] [SRC[>>3 5.]]。 [103] [[ES5]] の [CODE(JS)@[[[JSON.stringify]]]] は、 [[RFC]] ではなく [[ES5]] の規定に従って [[JSON]] を生成しなければなりません [SRC[>>36 15.12]]。これは [[RFC]] の規定より拡張された [[ES5]] の [[JSON]] を生成するので、 [[RFC]] の規定に基づく [[JSON生成器]] (>>85) には適合しません。 * 不正な JSON - [22] [[JSONP]] が [[JSON]] として扱われることがあります。 - [23] [[オブジェクト]]の[[特性名]]を表す[[文字列リテラル]]が [CODE(char)[[["]]]] で括られないことがあります。 - [24] [[JSON]] の前に「[CODE(JS)[[[var]] name = ]]」のような[[文字列]]がつくことがあります。 - [25] [[YAML]] の [[serializer]] によって実際には [[JSON]] ではない [[YAML]] が [[JSON]] であるとして出力されることがあります。 - [87] [[JavaScript]] の[[注釈]]が含まれることがあります。 - [88] [[配列]]や[[オブジェクト]]の最期の[[メンバー]]の後に [CODE(char)[[[,]]]] が余分に挿入されることがあります。 * JavaScript との互換性 [105] [[JavaScript]] の[[文字列リテラル]]では [CODE(char)[[[U+2028]]]] や [CODE(char)[[[U+2029]]]] を直接記述することは認められていませんが、 [[JSON]] では認められています [SRC[>>36 15.12.2]]。 [28] [CITE[JSON: The JavaScript subset that isn't — Timeless]] ([TIME[2011-05-16 04:05:34 +09:00]] 版) [27] [CITE[JSON::XS - search.cpan.org]] ([TIME[2011-04-15 12:50:01 +09:00]] 版) >One of the problems is that U+2028 and U+2029 are valid characters inside JSON strings, but are not allowed in ECMAscript string literals >Another problem is that some javascript implementations reserve some property names for their own purposes (which probably makes them non-ECMAscript-compliant). For example, Iceweasel reserves the __proto__ property name for it's own purposes. * YAML との互換性 [26] [[JSON]] は [[YAML]] の[[部分集合]]であるとの主張は'''嘘'''とされています。 ;; [CITE[JSON::XS - search.cpan.org]] ([TIME[2011-04-15 12:50:01 +09:00]] 版) * MIME 型 [89] [[JSON]] の [[MIME型]]は [DFN[[CODE(MIME)@en[[[application/json]]]]]] です [SRC[>>3 6.]]。 [90] この他 [DFN[[CODE(MIME)@en[[[*/*+json]]]]]] により [[JSON]] を使った特定の[[応用]]を表すことがあります。 ** CTE [91] [[CTE]] としては、 [[UTF-8]] を使う時は [CODE(MIME)@en[[[8bit]]]]、 [[UTF-16]] や [[UTF-32]] を使う時は [CODE(MIME)@en[[[binary]]]] が適切です。 [SRC[>>3 6.]] ** 引数 [92] [CODE(MIME)@en[[[application/json]]]] には[[引数]]が定義されていません。 [93] たまに [CODE(MIME)@en[[[charset]]]] [[引数]]が付けられていることがあります。 ** [CODE(MIME)@en[+json]] で終わる MIME 型 - [98] [CODE(MIME)@en[[[application/jsonml+json]]]] - [99] [CODE(MIME)@en[[[application/microdata+json]]]] * 拡張子 [94] [[JSON]] の[[拡張子]]には [CODE(file)@en[[[.json]]]] [SRC[>>3 6.]] がしばしば使われます。 * Macintosh ファイル型 [95] 古い [[Mac OS]] で[[ファイル]]の種類を表す[[符号]]としては [CODE[[[TEXT]]]] が使われます [SRC[>>3 6.]]。 * 素片識別子 [96] [[RFC]] では[[素片識別子]]には言及されていません。 [97] [[JSON]] では[[素片識別子]]は使われていません。 * [CODE(JS)@en[JSON]] オブジェクト (JavaScript) - [CODE(JS)@en[[[JSON.parse]]]] - [CODE(JS)@en[[[JSON.stringify]]]] ** 歴史 [9] [CITE[Re: Native JSON parsing API]] ([[Henri Sivonen]] 著, [TIME[2008-06-16 06:12:12 +09:00]] 版) > The JSON parsers I've used in non-browser contexts have been Draconian and incompatible with existing content such as output from del.icio.us, which can contain escaped single quotes, which isn't allowed in proper JSON. [10] [CITE[JSON Serialization (was Re: ES4 draft: Name)]] ([TIME[2008-04-01 12:34:49 +09:00]] 版) [11] [CITE[Re: Native JSON parsing API]] ([[Maciej Stachowiak ]] 著, [TIME[2008-06-14 08:43:00 +09:00]] 版) >Native JSON parsing is being considered for the next versions of ECMAScript (the 3.1 and 4 versions). It seems like a better fit there than in HTML5. If it ends up not being added to ECMAScript, I would propose it as a standalone spec for the W3C Web Apps WG. [12] [CITE@en[es3.1:json_support '''['''ES4 Wiki''']''']] ([TIME[2008-12-20 11:20:05 +09:00]] 版) [14] [CITE@ja-jp[2008/9/10 - Internet Explorer 8 のネイティブ JSON]] ([TIME[2009-02-02 22:11:29 +09:00]] 版) [15] [CITE@en-us[Firefox 3.1 for developers - MDC]] ([TIME[2009-02-08 18:25:06 +09:00]] 版) >ネイティブ JSON の DOM バインディング( bug 408838 ) 。 ** 実装 [13] [CITE@en-us[JSON - MDC]] ([TIME[2009-02-02 22:06:53 +09:00]] 版) [16] [CITE[JSON、8進数 - 素人がプログラミングを勉強するブログ]] ([TIME[2009-06-28 10:12:45 +09:00]] 版) >まず、0123のように、0以外で先頭が0の数値はJSONとして不正である。 >例えばJSON.parse("0123")を評価すると、IE8とWebKit(r45311)ではSyntaxErrorが投げられる。 > Firefox(20090617のナイトリー)では、123になる。 > http://www.json.org/json2.js:json2.jsとGoogle Chrome(3.0.191)では、83になる。 [18] [CITE@en-us[JSON - MDC]] ([TIME[2009-10-18 14:43:23 +09:00]] 版) * メモ [1] [CITE[Introducing JSON]] > [CODE[JSON]] (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. 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. ;; [29] リンク切れ [TIME[2011-08-24T11:10:03.000Z]] [2] ''Semantic Interpretation for Speech Recognition (SISR) Version 1.0'' ([[名無しさん]] [WEAK[2006-01-19 03:31:05 +00:00]]) [4] >>3 明記されていないけど [[BOM]] は使えないということでおk? ([[名無しさん]]) [5] 不適合文書の扱いも明記されていないけど、構文解析器は不適合も処理して'''構わない'''ことになっているから、 適当に理解するなりはじくなりでおk? ([[名無しさん]]) [6] [[サロゲート・ペア]]の片割れだけが escape されている場合は >>5? ([[名無しさん]]) [7] [CITE@ja-JP[Matzにっき(2007-04-16)]] ([[Yukihiro -matz- Matsumoto]] 著, [CODE[2007-04-23 23:58:26 +09:00]] 版) ([[名無しさん]] [WEAK[2007-05-05 03:25:51 +00:00]]) [8] [CITE@en[JSONLint - The JSON Validator.]] ([TIME[2008-06-22 12:32:25 +09:00]] 版) [17] [CITE[IRC logs: freenode / #whatwg / 20090906]] ([TIME[2009-10-17 22:08:59 +09:00]] 版) ;; [33] [[JSON]] の[[構文解析]]における互換性について。 [[RFC]] は非標準の拡張を理解することを認めている。 [[ES5]] はより厳密に定義している。古い案では[[注釈]]を認めていたが、 非標準の[[指令]]の埋込みに使われるようになったため、結局認めないことになった。 [19] [CITE[as3corelib の JSON.decode() をいい加減な JSON に対応させる - てっく煮ブログ]] ([TIME[2010-01-01 12:15:16 +09:00]] 版) [20] [CITE[IRC logs: freenode / #whatwg / 20100104]] ([TIME[2010-01-06 08:11:05 +09:00]] 版) ;; [32] [[JSON]] の[[文字符号化]]について。 [62] [[JSON]] の [[RFC]] はデータ型と構文上の要素と字句の関係を半ば暗黙のものとして扱っていて、 何がどう解釈されるかといったことを明確に規定していません。 ;; [63] こういうのが、 [[Hixie]] が [[BNF]] を使わない理由の1つだよなー。 [106] [CITE[PHPのイタい入門書を読んでAjaxのXSSについて検討した(3)~JSON等の想定外読み出しによる攻撃~ - ockeghem(徳丸浩)の日記]] ([TIME[2011-09-15 11:02:11 +09:00]] 版) [107] [CITE@en-US[An update is available for the native JSON feature in Internet Explorer 8]] ([TIME[2011-10-05 11:52:02 +09:00]] 版) [108] [CITE@en[Native JSON in IE8 - IEBlog - Site Home - MSDN Blogs]] ([TIME[2011-10-05 11:52:24 +09:00]] 版) [109] [CITE[IRC logs: freenode / #whatwg / 20111005]] ( ([TIME[2011-10-06 22:50:15 +09:00]] 版))