วิธีหลีกเลี่ยงอักขระพิเศษในการสร้างสตริง JSON


200

นี่คือสตริงของฉัน

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

ที่นี่ข้อความมีเครื่องหมายคำพูดเดี่ยวซึ่งเหมือนกับคำพูดที่ใช้ใน JSON สิ่งที่ฉันทำคือเติมสตริงจากอินพุตของผู้ใช้เช่นข้อความ ดังนั้นฉันต้องหลบหนีสถานการณ์พิเศษเหล่านั้นที่ทำลายรหัส แต่นอกเหนือจากการแทนที่ด้วยสตริงมีวิธีใดบ้างที่จะทำให้พวกเขาหลบหนี แต่ยังคงอนุญาตให้ HTML ประมวลผลพวกเขากลับไปเป็นข้อความที่ถูกต้องหรือไม่


45
JSON ใช้เครื่องหมายคำพูดคู่เท่านั้นไม่ใช่เครื่องหมายคำพูดเดี่ยวดูjson.org
Niels Bom

4
RFC 4627 ระบุว่า parsers ต้องสามารถวิเคราะห์คำสั่ง JSON (ย่อหน้า 4) และอาจสนับสนุนส่วนขยายที่ไม่ใช่ JSON เพิ่มเติม อย่างไรก็ตามย่อหน้าที่ 5 ระบุอย่างชัดเจนว่าผู้ผลิตทั้งหมด (เครื่องกำเนิดไฟฟ้า) ต้องผลิต JSON ที่เข้ากันได้ 100% เท่านั้น การสร้าง JSON ด้วยอักขระเฟรมที่ไม่ต้องการหลบหนีเป็นแนวคิดที่ไม่ดีเป็นพิเศษ โปรดลองเปลี่ยนเครื่องหมายอัญประกาศเดี่ยวของคุณด้วยเครื่องหมายคำพูด ietf.org/rfc/rfc4627.txt
Luv2code

3
@ Luv2code ในขณะที่คะแนนของคุณยังคงเป็นจริงโปรดทราบว่าคุณอ้างถึงข้อมูลจำเพาะที่ล้าสมัย เมื่ออ่าน RFCs ให้ใช้tools.ietf.org/htmlเวอร์ชันเสมอไม่ใช่เวอร์ชันข้อความ เวอร์ชัน HTML นั้นง่ายต่อการอ่านและเชื่อมโยงไปยังส่วนย่อยและที่สำคัญที่สุดคือด้านบนสุดของเวอร์ชัน HTML คือรายการ RFC ที่ตามมาทั้งหมดที่อัปเดตหรือล้าสมัยที่คุณอ่านอยู่ หากคุณต้องการไปtools.ietf.org/html/rfc4627คุณจะได้เห็นว่า RFC 4627 เป็นล้าสมัยและได้รับการแทนที่ด้วยRFC 7159
Mark Amery

3
สำหรับคนที่อ่านสิ่งนี้ในอนาคต RFC 7159 ได้ถูกเลิกใช้แล้วโดย tools.ietf.org/html/rfc8259
Joram van den Boezem

คำตอบ:


286

สตริง JSON ต้องยกมาสองครั้งตามรายละเอียด'เพื่อให้คุณไม่จำเป็นที่จะหลบหนี
หากคุณต้องใช้อักขระพิเศษในสตริง JSON ของคุณคุณสามารถหนีโดยใช้\อักขระ

ดูรายการอักขระพิเศษที่ใช้ใน JSON:

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


\'อย่างไรก็ตามแม้ว่าจะมีทั้งหมดตรงกันข้ามกับสเปคที่ผู้เขียนสามารถใช้

สิ่งนี้ไม่ดีเพราะ:

  • มันขัดกับรายละเอียด
  • มันเป็นสตริงที่ไม่ถูกต้องของ JSON

แต่มันใช้งานได้ตามที่คุณต้องการหรือไม่

สำหรับผู้อ่านใหม่ให้ใช้เครื่องหมายคำพูดคู่สำหรับสตริง json ของคุณเสมอ


30
"สตริง json ที่ยกมาเดี่ยว" ? นี่เป็นเรื่องไร้สาระ; สตริงใน JSON สามารถเป็นสองครั้งที่ยกมา ลองJSON.parse("'foo'")ในคอนโซลเบราว์เซอร์ของคุณตัวอย่างเช่น, SyntaxError: Unexpected token 'และสังเกต ข้อมูลจำเพาะของ JSON นั้นเรียบง่ายและชัดเจนมาก ไม่มีลำดับ escape ใน JSON สำหรับเครื่องหมายคำพูดเดี่ยวและสตริง JSON ไม่สามารถอ้างอิงแบบเดี่ยวได้
Mark Amery

15
แม้แต่การอัพเดทที่ชัดเจนในคำตอบนี้ก็ไม่ดี ในขณะที่ความจริงทางเทคนิคมันเป็นความเข้าใจผิดที่จะบอกว่าคุณ"ไม่จำเป็น" ที่จะหลบหนี'ในลักษณะเดียวกับที่มันเป็นความจริงทางเทคนิค แต่ทำให้เข้าใจผิดที่จะบอกว่าตามกฎหมายคุณไม่จำเป็นต้องฆ่าเด็ก ที่ถูกต้องมากขึ้นจะบอกว่าคุณไม่สามารถ'หลบหนี \'เป็นลำดับการหลบหนีที่ผิดกฎหมายและหากคุณใช้งาน JSON ของคุณจะไม่ถูกต้อง JSONและตัวแยกวิเคราะห์ JSON ใด ๆ จะทำให้หายใจไม่ออก (แน่นอนว่า JavaScript JSON.parseและ Python json.loadsทำ)
Mark Amery

2
คำตอบนี้ยังคงไร้สาระที่สุดหลังจากการแก้ไขหลายอย่าง คุณเรียกร้องผิดว่าการใช้สายเดียวที่ยกมาใน JSON และการใช้\'ลำดับหนี"ผลงานตามที่คุณต้องการหรือไม่" นี่เป็นเท็จ ฉันขอท้าให้คุณแสดงตัวแยกวิเคราะห์ JSON ใด ๆในการใช้ที่เป็นที่นิยมซึ่งจะไม่ทำให้หายใจไม่ออกในสตริงที่ยกมาเดี่ยวหรือ\'ตามลำดับ ฉันได้ชี้ให้เห็นแล้วว่าJSON.parse("'foo'")และJSON.parse('"\\\'"') (ใน JavaScript) json.loads("'foo'")และjson.loads('"\\\'"')(ใน Python) ทั้งโยนข้อยกเว้น อะไรคือพื้นฐานของคุณสำหรับการกล่าวอ้างว่าการใช้โครงสร้าง "งาน" เหล่านี้?
Mark Amery

10
@ Luv2code อ้างที่น่าสนใจ คุณตีความผิดเล็กน้อย มันไม่ได้หมายความว่าตัวละครใด ๆ ที่สามารถหนีออกมาได้ง่ายๆโดยการใส่เครื่องหมายในด้านหน้าของมัน ข้อความที่อ้างถึงแบบเต็มคือ "อักขระใด ๆ อาจหนีได้หากตัวละครอยู่ในระนาบ Multilingual หลายภาษา (U + 0000 ถึง U + FFFF) แสดงว่าอาจมีลำดับหกตัวอักษร ... หรืออีกวิธีหนึ่งคือมีสอง การแทนลำดับตัวอักษร - อักขระของอักขระยอดนิยมบางตัว "(เหมืองของเราเน้น) มันบอกว่าคุณสามารถหลบหนี'เป็น\u0027, ไม่\'ว่าคุณสามารถหลบหนีเป็น
Mark Amery

2
@ Luv2code ยังหมายความว่าความคิดเห็นที่อัปเดตของฉันระบุว่า "คุณไม่สามารถหลบหนี'" (และการเปรียบเทียบการกระทำดังกล่าวกับการสังหารเด็ก!) เป็นความผิดทางเทคนิค \'ถูกต้องมากขึ้นคือจะบอกว่าคุณสามารถหลบหนีมันก็ไม่เป็น ฉันไม่ได้ตระหนักว่าสเปครุ่น RFC ที่อ้างถึงลำดับนั้น\u0027เป็นวิธีการ 'หนี' ตัวละครที่พวกเขาเป็นตัวแทน จุดสำคัญที่\'ผิดกฎหมายยังคงเป็นจริงและสำคัญ
Mark Amery

362

ฉันรู้สึกตกใจกับการมีข้อมูลที่ผิดที่ได้รับความนิยมสูงในคำถามที่มีผู้เข้าชมสูงเกี่ยวกับหัวข้อพื้นฐาน

สตริง JSON ไม่สามารถยกมาด้วยคำพูดเดียว ข้อมูลจำเพาะรุ่นต่าง ๆ ( ต้นฉบับโดย Douglas Crockford, รุ่น ECMAและรุ่น IETF ) ทุกสถานะที่สตริงต้องถูกยกมาด้วยเครื่องหมายคำพูดคู่ นี่ไม่ใช่ประเด็นทางทฤษฎีหรือเป็นเรื่องของความเห็นตามคำตอบที่ได้รับการยอมรับในปัจจุบัน ตัวแยกวิเคราะห์ JSON ใด ๆ ในโลกแห่งความเป็นจริงจะเกิดข้อผิดพลาดหากคุณพยายามแยกวิเคราะห์สตริงที่มีเครื่องหมายคำพูดเดี่ยว

เวอร์ชันของ Crockford และ ECMA ยังแสดงคำจำกัดความของสตริงโดยใช้รูปภาพที่สวยซึ่งควรทำให้จุดชัดเจนอย่างไม่น่าสงสัย:

รูปภาพแสดงนิยามของสตริงจากข้อมูลจำเพาะ JSON

รูปภาพสวย ๆ ยังแสดงรายการ escape sequences ที่ถูกต้องทั้งหมดภายในสตริง JSON:

  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u ตามด้วยตัวเลขสี่หลักฐานสิบหก

โปรดทราบว่าตรงข้ามกับคำตอบที่ไร้สาระในที่นี้ \'จะไม่มีลำดับการหลบหนีที่ถูกต้องในสตริง JSON ไม่จำเป็นต้องเป็นเพราะสตริง JSON เป็นเครื่องหมายคำพูดคู่เสมอ

ท้ายที่สุดคุณไม่ควรคิดจะหนีจากตัวคุณเองเมื่อสร้าง JSON แบบเป็นโปรแกรม (แต่แน่นอนว่าคุณจะต้องแก้ไขไฟล์ JSON ที่ใช้ JSON ด้วยตนเอง) แต่ให้สร้างโครงสร้างข้อมูลที่คุณต้องการเข้ารหัสโดยใช้แผนที่เนทีฟอาเรย์สตริงจำนวนบูลีนและ null ที่เป็นภาษาของคุณจากนั้นเข้ารหัสเป็น JSON ด้วยฟังก์ชันการเข้ารหัส JSON ฟังก์ชั่นดังกล่าวอาจสร้างขึ้นในภาษาที่คุณใช้เช่น JavaScript JSON.stringify, PHP json_encodeหรือ Pythonjson.dumps. หากคุณกำลังใช้ภาษาที่ไม่มีฟังก์ชั่นดังกล่าวติดตั้งอยู่คุณอาจพบ JSON ในการแยกวิเคราะห์และเข้ารหัสไลบรารีที่จะใช้ หากคุณเพียงแค่ใช้ฟังก์ชั่นภาษาหรือไลบรารีเพื่อแปลงสิ่งของเป็นและจาก JSON คุณจะไม่จำเป็นต้องรู้กฎการหลบหนีของ JSON เลย นี่คือสิ่งที่ผู้ถามคำถามที่เข้าใจผิดที่นี่ควรจะทำ


4 ไบต์ฐานสิบหกหรือnibbles ?
leetbacoon

36

ทุกคนกำลังพูดถึงวิธีการหลบหนี'ใน'สตริงตัวอักษรที่ยกมา มีปัญหาที่ใหญ่มากที่นี่: เดียวยกสายอักขระตัวอักษรไม่ได้ JSON JSON นั้นใช้ JavaScript แต่มันก็ไม่เหมือนกัน หากคุณกำลังเขียนวัตถุตามตัวอักษรในรหัส JavaScript ให้ปรับ; ถ้าคุณต้องการจริง JSON "คุณจำเป็นต้องใช้

'กับสตริงยกมาสองครั้งแล้วคุณจะไม่จำเป็นที่จะหลบหนี (และถ้าคุณต้องการตัวอักษร"ในสตริงคุณจะใช้\")


1
'สวัสดีคุณกล่าวว่ากับสตริงยกมาสองครั้งแล้วคุณจะไม่จำเป็นที่จะหลบหนี ตัวอย่างศัตรูหากค่าสตริงของฉันคือ"Member's_id" : 4คุณกำลังบอกว่ามันไม่จำเป็นต้องหลบหนี? เห็นได้ชัดว่าฉันกำลังมีปัญหาที่ทำให้มันมีข้อผิดพลาดของการเข้ารหัสผิด: UTF-8 Member�sและมันจะถูกอ่านเป็น มันเป็นไฟล์ json ที่สร้างขึ้นด้วยตนเอง
Shubham

1
'ในตัวอักษรสตริง JSON จะต้องไม่หนี คุณคัดลอกวางมาจากที่อื่นหรือไม่ บางทีมันอาจจะเป็น a \u2019, ไม่ใช่อะพอสโทรฟี ฉันเดาว่า: มีคนพิมพ์ลงใน MS Word ซึ่งเปลี่ยนเป็นเครื่องหมายคำพูดเพราะคิดว่ารู้ดีที่สุด ตามหลักไวยากรณ์แล้วอักขระ ASCII ตัวเก่าที่ดี ( 'หรือ\x27ที่เราเคยเรียกกันว่า "อัญประกาศเดี่ยว" จนถึงปัจจุบัน) คือสิ่งที่คุณต้องการ แต่มันจะเป็นการดีถ้าคุณแก้ไขปัญหาการเข้ารหัสอักขระในกรณีที่มีปัญหาอื่น ๆ ที่คล้ายคลึงกัน ดังนั้นเลือกการเข้ารหัสตัวอักษรและใช้สำหรับทั้งการอ่านและการเขียน \uหรือหลบหนีโดยใช้
David Knipe

7

คำตอบส่วนใหญ่ไม่ตอบคำถามหรือมีความยาวเกินความจำเป็นในการอธิบาย

ตกลงดังนั้น JSON จะใช้เครื่องหมายอัญประกาศคู่เท่านั้นเราเข้าใจแล้ว!

ฉันพยายามใช้ JQuery AJAX เพื่อโพสต์ข้อมูล JSON ไปยังเซิร์ฟเวอร์จากนั้นส่งคืนข้อมูลเดิมในภายหลัง ทางออกที่ดีที่สุดสำหรับคำถามที่โพสต์ที่ฉันพบคือการใช้:

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

นี่จะเป็นการหลบหนีตัวละครสำหรับคุณ

สิ่งนี้ได้รับการแนะนำโดย Mark Amery คำตอบที่ยอดเยี่ยม BTW

หวังว่านี่จะช่วยใครซักคน


0

อาจเป็นฉันสายเกินไปที่จะเลี้ยง แต่สิ่งนี้จะแยก / หลบหนีอ้างเดี่ยว (ไม่ต้องการเข้าสู่การต่อสู้กับการแยกวิเคราะห์เทียบกับหลบหนี)

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

0

คำตอบของคำถามโดยตรง:
เพื่อความปลอดภัยให้แทนที่อักขระที่ต้องการด้วย \ u + 4-digit-hex-value

ตัวอย่าง: หากคุณต้องการหลีกเลี่ยงเครื่องหมายอะโพสโทรฟี 'แทนที่ด้วย \ u0027
D'Amico กลายเป็น D \ u0027Amico

การอ้างอิงที่ดี: http://es5.github.io/x7.html#x7.8.4

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


-1 สำหรับการอ้างอิง คำถามคือเกี่ยวกับ JSON แต่การอ้างอิงการเชื่อมโยงของคุณเกี่ยวกับ JavaScript และรายชื่อลำดับหนีที่ไม่ถูกต้องใน JavaScript \'เช่น
Mark Amery

ขอบคุณ Mark - ฉันแค่อยากให้มุมมองอื่น - ขึ้นอยู่กับว่าใครมาที่นี่อาจพบว่ามีประโยชน์ แต่ฉันให้ความสำคัญกับ JSON และ Javascript - ขอบคุณที่เป็นนินจาในฟอรัม
Luigi D'Amico

0

ใช้ encodeURIComponent () เพื่อเข้ารหัสสตริง

เช่น. var product_list = encodeURIComponent (JSON.stringify (product_list));

คุณไม่จำเป็นต้องถอดรหัสเนื่องจากเว็บเซิร์ฟเวอร์ทำเช่นเดียวกันโดยอัตโนมัติ



-2

ฉันคิดว่าเราทุกคนเห็นด้วย jsons ที่ยกมาเดี่ยวไม่ใช่ jsons จริง หากเป็นไปได้เรายังคงต้องตอบคำถามเกี่ยวกับการหลบหนี "ภายในสตริง json ที่ยกมาเป็นสองเท่าในกรณีที่ไม่มีห้องสมุดให้ทำเพื่อเรา

การแทนที่ "with a" แต่ละรายการไม่เพียงพอ: ผู้ใช้สามารถป้อนอินพุต: \ และการแยกวิเคราะห์อีกครั้งล้มเหลว (คิดว่าเพราะอะไร)

ก่อนอื่นให้แทนที่แต่ละ \ ด้วย \ (แบ็กสแลชคู่) จากนั้นให้แทนที่ "ด้วย \" แต่ละรายการ (แบ็กสแลชตามด้วย ")


-2

ในการอนุญาตให้ใช้อัญประกาศเดี่ยวภายในสตริงที่ยกมาเป็นทวีคูณเพื่อจุดประสงค์ของ json คุณต้องเพิ่มเครื่องหมายคำพูดเดี่ยวสองเท่า {"X": "คำถามคืออะไร"} ==> {"X": "คำถามคืออะไร"}

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

ลำดับ \ 'ไม่ถูกต้อง


2
การเพิ่มเครื่องหมายคำพูดเดี่ยวในสตริง JSON ไม่เพิ่มขึ้น มันหมายถึงสตริงของคุณมีสองคำพูดเดียวแทนที่จะเป็นหนึ่ง
Mark Amery

-15

เกี่ยวกับการโพสต์ของ AlexB:

 \'  Apostrophe or single quote
 \"  Double quote

การยกเว้นเครื่องหมายอัญประกาศเดี่ยวจะใช้ได้เฉพาะในสตริง json ที่ยกมาเดี่ยวการ
ยกเว้นเครื่องหมายอัญประกาศคู่นั้นจะใช้ได้เฉพาะในสตริง json ที่ยกมาสองเท่าเท่านั้น

ตัวอย่าง:

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

14
สตริงที่ยกมาเดี่ยวไม่ถูกกฎหมายใน JSON JSON ไม่ใช่ javascript JSON ไม่อนุญาตให้ออกจากเครื่องหมายคำพูดเดี่ยว ดูjson.orgสำหรับเอกสารง่าย ๆ ของไวยากรณ์ JSON
srm

3
downvote - เพราะคำพูดเดียว jsons ไม่ถูกต้อง!
DominikAngerer

เครื่องหมายคำพูดเดี่ยวไม่ถูกต้องใน json โปรดแสดงตัวอย่างการทำงานหากเป็นไปได้
Rohith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.