JSON dizesi oluştururken özel karakterlerden nasıl kaçılır?


202

İşte benim dizem

{
    'user': {
        'name': 'abc',
        'fx': {
            'message': {
                'color': 'red'
            },
            'user': {
                'color': 'blue'
            }
        }
    },
    'timestamp': '2013-10-04T08: 10: 41+0100',
    'message': 'I'mABC..',
    'nanotime': '19993363098581330'
}    

Burada ileti, JSON'da kullanılan tırnak ile aynı olan tek tırnak işareti içerir. Ne yapmak gibi mesaj gibi kullanıcı girişlerinden bir dize doldurmaktır. Yani, kodu kıran özel senaryolardan kaçmam gerekiyor. Ancak dize yerine başka, kaçmak için ama HTML tekrar doğru iletiye geri işlemesine izin için herhangi bir yolu var mı?


46
JSON yalnızca çift tırnak kullanır, tek tırnak kullanmaz, bkz. Json.org
Niels Bom

4
RFC 4627, ayrıştırıcıların uyumlu JSON'u (paragraf 4) ayrıştırması gerektiğini ve ek JSON olmayan uzantıları destekleyebileceğini belirtir. Bununla birlikte, paragraf 5, tüm üreticilerin (jeneratörler) SADECE% 100 uyumlu JSON üretmesi gerektiğini vurgulamaktadır. Kaçmaya gerek olmayan kare karakterleriyle JSON üretmek özellikle kötü bir fikirdir. Lütfen kesme işaretlerinizi tırnak işareti ile değiştirmeyi düşünün. ietf.org/rfc/rfc4627.txt
Luv2code

3
@ Luv2code Belirttiğiniz noktalar doğru kalırken, eski bir spesifikasyona atıfta bulunduğunuzu unutmayın. RFC'leri okurken , metin sürümünü değil , her zaman tools.ietf.org/html sürümünü kullanın . HTML sürümlerinin okunması ve alt bölümlerine bağlanması daha kolaydır ve en önemlisi, HTML sürümlerinin en üstünde, okuduklarınızı güncelleyen veya geçersiz kılan sonraki tüm RFC'lerin bir listesi bulunur. Tools.ietf.org/html/rfc4627 adresine gitmiş olsaydınız , RFC 4627'nin eski olduğunu ve yerine RFC 7159 geçtiğini görmüştünüz .
Mark Amery

3
Gelecekte bunu okuyan insanlar için, RFC 7159 sırasıyla tools.ietf.org/html/rfc8259
Joram van den Boezem

Yanıtlar:


287

Bir JSON dizesi göre, çift tırnaklı olmalıdır özellikleri kaçmak gerek kalmaz, '.
JSON dizenizde özel karakter kullanmanız gerekiyorsa, \karakter kullanarak bu karakterden kaçabilirsiniz .

JSON'da kullanılan bu özel karakter listesine bakın:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\\  Backslash character


Ancak, spesifikasyona tamamen aykırı olsa bile, yazar kullanabilir \'.

Bu kötü çünkü:

  • Bu özelliklerin aksine
  • Artık JSON geçerli bir dize değil

Ama istediğin gibi çalışıyor ya da değil.

Yeni okuyucular için, json dizeleriniz için her zaman çift tırnak kullanın.


30
"tek tırnaklı json dizeleri" ? Bu saçmalık; JSON'daki dizeler yalnızca çift tırnak içine alınabilir. JSON.parse("'foo'")Örneğin, tarayıcı konsolunuzda deneyin ve SyntaxError: Unexpected token '. JSON spec bu konuda gerçekten basit ve açık . Tek tırnak için JSON'da kaçış sırası yoktur ve bir JSON dizesi tek tırnak içine alınamaz.
Mark Amery

15
Bu cevaba yapılan sözde güncelleme bile kötü. Teknik olarak doğru olsa da, teknik olarak doğru olduğu gibi kaçmak için "gerek duymadığınızı"' söylemek yanıltıcıdır, ancak yasal olarak çocukları öldürmeniz gerekmediğini söylemek yanıltıcıdır . Daha doğru size söylemek olurdu olamaz kaçış '. \'geçersiz bir kaçış dizisidir ve kullanırsanız JSON'niz geçerli JSON değildir ve herhangi bir JSON ayrıştırıcısı bunu boğar. (Kesinlikle JavaScript JSON.parseve Python'un yaptığı json.loads.)
Mark Amery

2
Bu cevap birçok düzenlemeden sonra tamamen saçmalıktır. Yanlışlıkla, JSON'da tek tırnaklı dizeler kullanmanın ve \'kaçış dizisinin "istediğiniz gibi çalıştığından" çalıştığını iddia edersiniz . Bu yanlış. Tek tırnaklı dizelerde veya dizide boğulmayacak popüler kullanımdaki herhangi bir JSON ayrıştırıcısını sergilemeniz için size meydan okuyorum \'. Zaten JSON.parse("'foo'")ve JSON.parse('"\\\'"') (JavaScript'te) json.loads("'foo'")ve json.loads('"\\\'"')(Python'da) her ikisinin de istisnalar attığına işaret ettim . Bu yapıları kullanmanın "işe yaradığı" iddiasının temeli nedir ?
Mark Amery

10
@ Luv2code ilginç alıntı. Biraz yanlış yorumluyorsun; o değil herhangi bir karakter önünde ters eğik çizgi koyarak sadece kaçmış olabilir anlamına gelir. Daha dolgun bir alıntı "Herhangi bir karakter kaçabilir. Karakter Temel Çok Dilli Düzlemde ise (U + 0000 - U + FFFF), o zaman altı karakterlik bir dizi olarak temsil edilebilir . ... Alternatif olarak, iki - bazı popüler karakterlerin karakter dizisi kaçış gösterimleri . "(vurgu benim). Kaçabilir söylüyor 'olarak \u0027, değil sen olarak kaçabilmesi \'.
Mark Amery

2
@ Luv2code hala, "kaçamayacağınızı '" (ve böyle bir eylemi çocukların öldürülmesi ile karşılaştırmak!) daha isabetli bir şekilde ondan kaçabileceğinizi söylemektir \'. Spesifikasyonların RFC versiyonunun, \u0027temsil ettikleri karakterlerden 'kaçma' yolu gibi dizilere atıfta bulunduğunu fark etmemiştim . \'Yasadışı olan anahtar nokta , yine de doğru ve önemlidir.
Mark Amery

363

Temel bir konu hakkında bu kadar çok görüntülenen bir soru üzerinde çok iyi değerlendirilmiş yanlış bilginin varlığı beni dehşete düşürdü.

JSON dizeleri tek tırnak içine alınamaz . Spesifikasyonun çeşitli versiyonları ( Douglas Crockford tarafından orijinal , ECMA versiyonu ve IETF versiyonu ), dizelerin çift tırnakla alıntılanması gerektiğini belirtir. Bu teorik bir konu ya da kabul edilen cevabın önerdiği gibi bir görüş meselesi değildir; tek tırnaklı bir dizeyi ayrıştırmaya çalışırsanız, gerçek dünyadaki herhangi bir JSON ayrıştırıcısı hata verir.

Crockford'un ve ECMA'nın sürümü, noktayı açık bir şekilde netleştirmesi gereken güzel bir resim kullanarak bir dizenin tanımını bile görüntüler:

JSON spesifikasyonundan bir dizenin tanımını gösteren resim

Güzel resim ayrıca bir JSON dizesindeki tüm meşru kaçış dizilerini listeler:

  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u ardından dört haneli rakam

Burada diğer bazı cevaplardaki saçmalıkların aksine \', bir JSON dizesinde asla geçerli bir kaçış dizisi olmadığını unutmayın. Bunun olması gerekmez, çünkü JSON dizeleri her zaman çift tırnaklıdır.

Son olarak, programlı olarak JSON oluştururken karakterlerden kaçmayı düşünmek zorunda kalmamalısınız (tabii ki elle JSON tabanlı bir yapılandırma dosyası düzenlerken de yapacaksınız). Bunun yerine, dilinizin sahip olduğu yerel eşleme, dizi, dize, sayı, boole ve null türlerini kullanarak kodlamak istediğiniz veri yapısını oluşturun ve ardından JSON'a bir JSON kodlama işleviyle kodlayın. Böyle bir işlev muhtemelen JavaScript JSON.stringify, PHP json_encodeveya Python gibi hangi dili kullandığınıza bağlıdır.json.dumps. Yerleşik böyle bir işlevselliğe sahip olmayan bir dil kullanıyorsanız, muhtemelen kullanılacak bir JSON ayrıştırma ve kodlama kitaplığı bulabilirsiniz. JSON'a ve JSON'dan bir şeyler dönüştürmek için dil veya kütüphane işlevlerini kullanırsanız, JSON'un kaçan kurallarını bile bilmeniz gerekmez. Buradaki yanlış yönlendirilmiş soru askerin yapması gereken şey budur.


4 onaltılık bayt veya nibble ?
leetbacoon

36

Herkes alıntılanmış 'bir 'dizgiden nasıl kaçacağından bahsediyor . Burada çok daha büyük bir sorun var: tek tırnaklı dize değişmez değerleri geçerli JSON değil . JSON JavaScript tabanlıdır, ancak aynı şey değildir. JavaScript kodu içine bir nesne hazır bilgisi yazıyorsanız, para cezası; aslında JSON'a ihtiyacınız varsa kullanmanız gerekir ".

Çift tırnaklı dizelerle, kaçmak zorunda kalmazsınız '. (Ve "dizede değişmez bir kelime isteseydiniz, kullanırsınız \".)


1
Merhaba, çift tırnaklı dizelerle, kaçmanız gerekmeyeceğini söylediniz '. Düşman örneği benim dize değeri, "Member's_id" : 4kaçmak gerekmez diyor musunuz? Görünüşe göre yanlış kodlama hatası veren bir sorun yaşıyorum: UTF-8 ve o olarak okunuyor Member�s. Onun el ile oluşturulan bir json dosyası.
Shubham

1
'JSON dizesinde değişmez değerden kaçınılmalıdır. Bir yerden kopyalayıp yapıştırdınız mı? Belki bu \u2019bir kesme işareti değil, gerçekten bir . Benim tahminim: birisi MS Word'e yazdı, bu onu bir tırnak işareti haline getirdi çünkü en iyi bildiğini düşünüyor. Grammatik olarak, eski ASCII karakter kesme işareti ( şu ana kadar "tek tırnak" olarak adlandırdığımız 'aka \x27) istediğiniz. Ancak, benzer sorunlar olması durumunda, karakter kodlama sorununuzu düzeltmek yine de iyi olur. Bu yüzden bir karakter kodlaması seçin ve hem okuma hem de yazma için kullanın. Veya kullanarak kaçmak \u.
David Knipe

7

Bu cevapların çoğu ya soruyu cevaplamıyor ya da açıklamada gereksiz yere uzun.

Tamam JSON sadece çift tırnak işaretleri kullanıyor, anlıyoruz!

JQuery AJAX sunucuya JSON veri göndermek ve daha sonra aynı bilgileri döndürmek için kullanmaya çalışıyordu. Bulduğum soruya en iyi çözüm kullanmaktı:

var d = {
    name: 'whatever',
    address: 'whatever',
    DOB: '01/01/2001'
}
$.ajax({
    type: "POST",
    url: 'some/url',
    dataType: 'json',
    data: JSON.stringify(d),
    ...
}

Bu sizin için karakterlerden kaçacaktır.

Bu da Mark Amery, Büyük cevap BTW tarafından önerildi

Umarım bu birine yardımcı olur.


0

Ben partiye çok geç olabilir ama bu tek teklif ayrıştırmak / kaçmak (ayrışmak vs kaçış ayrıştırma bir savaşa girmek istemiyorum) ..

JSON.parse("\"'\"")

0

Doğrudan soruyu cevaplayın:
Güvende olmak için, gerekli karakteri \ u + 4 basamaklı onaltılık değerle değiştirin

Örnek: Kesme işaretinden kaçmak istiyorsanız \ u0027 ile değiştirin
D'Amico D \ u0027Amico olur

GÜZEL REFERANS: http://es5.github.io/x7.html#x7.8.4

https://mathiasbynens.be/notes/javascript-escapes


Referanslar için -1. Soru JSON ile ilgili, ancak bağlantılı referanslarınız JavaScript ile ilgilidir ve JavaScript gibi geçerli olmayan kaçış dizilerini listeler \'.
Mark Amery

Teşekkürler Mark - Gerçekten sadece alternatif bir açı vermek istedim - buraya gelenlere bağlı olarak bu yararlı olabilir. Ancak JSON & Javascript ile ilgili görüşlerinizi dile getiriyorum - Forumlarda Ninja olduğunuz için teşekkürler.
Luigi D'Amico

0

Dizeyi kodlamak için encodeURIComponent () öğesini kullanın.

Örneğin. var product_list = encodeURIComponent (JSON.stringify (product_list));

Web sunucusu otomatik olarak aynı şeyi yaptığından kodu çözmenize gerek yoktur.


0

Şablon değişmezlerini kullanma ...

var json = `{"1440167924916":{"id":1440167924916,"type":"text","content":"It's a test!"}}`;

-2

Sanırım hepimiz tek tırnaklı jsonların gerçek jsons olmadığını kabul ediyoruz. Olabildiğince, bizim için bunu yapmaya kütüphanelerin yokluğunda hala "çift tırnaklı bir json dizesi içinde kaçma" sorununu ele almamız gerekiyor.

Her bir "\" ile değiştirmek YETERLİ DEĞİL: Kullanıcı girdiyi girebilir: \ ve yine ayrıştırma başarısız olur (nedenini düşünün).

Bunun yerine, önce her bir \ \ (çift ters eğik çizgi) ile değiştirin. Ancak bundan sonra, her bir "\" (ters eğik çizgi ve ardından ") ile değiştirin.


-2

Json amacıyla çift tırnaklı dize içinde tek tırnaklara izin vermek için tek tırnak iki katına çıkar. {"X": "Soru nedir"} ==> {"X": "Soru nedir"}

/codereview/69266/json-conversion-to-single-quotes

\ 'Dizisi geçersiz.


2
Bir JSON dizesinde tek bir alıntıyı ikiye katlamak bundan kaçmaz. Bu, dizenizin bir yerine iki tek tırnak içerdiği anlamına gelir.
Mark Amery

-15

AlexB'in gönderisine ilişkin:

 \'  Apostrophe or single quote
 \"  Double quote

tek tırnaktan kaçmak sadece tek tırnaklı json dizelerinde
geçerlidir çift tırnak kaçan sadece çift tırnaklı json dizelerinde geçerlidir

misal:

'Bart\'s car'       -> valid
'Bart says \"Hi\"'  -> invalid

14
Tek tırnaklı dizeler JSON'da yasal değildir. JSON javascript değildir. JSON tek tırnaktan kaçmaya izin vermez. JSON sözdiziminin çok basit bir belgesi için json.org adresine bakın .
srm

3
downvote - çünkü tek tırnak jsons geçerli değil!
DominikAngerer

Tek tırnak json içinde geçersiz. Mümkünse lütfen çalışan bir örnek gösterin
Rohith
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.