क्या करता है "सामग्री-प्रकार: आवेदन / json; charset = utf-8 ”वास्तव में मतलब है?


284

जब मैं अपनी REST सेवा के लिए JSON निकाय के साथ एक POST अनुरोध करता हूं तो मैं Content-type: application/json; charset=utf-8संदेश हेडर में शामिल करता हूं । इस हेडर के बिना, मुझे सेवा से एक त्रुटि मिलती है। मैं भी सफलतापूर्वक भाग के Content-type: application/jsonबिना उपयोग कर सकते हैं ;charset=utf-8

वास्तव में क्या करता charset=utf-8है? मुझे पता है कि यह चरित्र एन्कोडिंग को निर्दिष्ट करता है लेकिन सेवा इसके बिना ठीक काम करती है। क्या यह एन्कोडिंग उन वर्णों को सीमित करता है जो संदेश निकाय में हो सकते हैं?


4
पर एक नज़र डालें hanselman.com/blog/...
डैनियल पॉवेल

8
जाहिर है, आईएएनए के application/jsonमीडिया प्रकार पंजीकरण के अनुसार, charsetसभी में एक समर्थित पैरामीटर नहीं दिखता है , यद्यपि व्यवहार में अक्सर आपूर्ति की जाती है।
Uux

1
I know it specifies the character encoding but the service works fine without it."वर्किंग" का हमेशा मतलब नहीं होता है "अस्तित्व कोड / कॉन्फ़िगरेशन एक कोने से सभी मामलों को कवर करने का सबसे सही तरीका है"। यह सभी सम्मेलनों और मान्यताओं पर निर्भर करता है जो अन्य परिस्थितियों में काम नहीं कर सकते हैं। मेरे लिए व्यक्तिगत रूप से, मैं हमेशा यथासंभव स्पष्ट होने की कोशिश करता हूं।
पश्चिमीगुन

3
"चारसेट" पैरामीटर भेजना गलत और अर्थहीन है। RFC 8259, धारा 11, अंतिम वाक्य देखें।
जूलियन रेसचेक

जवाबों:


283

शीर्ष लेख केवल यह बताता है कि सामग्री किस सामग्री में इनकोड की गई है। आवश्यक नहीं है कि सामग्री से ही सामग्री के प्रकार को कम करना संभव है, अर्थात आप आवश्यक रूप से केवल सामग्री को नहीं देख सकते हैं और यह जान सकते हैं कि इसके साथ क्या करना है। जो HTTP हेडर के लिए हैं, वे प्राप्तकर्ता को बताते हैं कि वे किस तरह की सामग्री (माना जाता है) के साथ काम कर रहे हैं।

Content-type: application/json; charset=utf-8सामग्री को JSON प्रारूप में होना चाहिए, UTF-8 वर्ण एन्कोडिंग में एन्कोडेड। एन्कोडिंग को डिजाइन करना JSON के लिए कुछ हद तक बेमानी है, क्योंकि JSON के लिए डिफ़ॉल्ट (केवल?) एन्कोडिंग UTF-8 है। तो इस मामले में प्राप्तकर्ता सर्वर जाहिरा तौर पर यह जानकर खुश है कि यह JSON के साथ काम कर रहा है और यह मानता है कि एन्कोडिंग UTF-8 डिफ़ॉल्ट रूप से है, इसीलिए यह हेडर के साथ या इसके बिना काम करता है।

क्या यह एन्कोडिंग उन वर्णों को सीमित करता है जो संदेश निकाय में हो सकते हैं?

नहीं। आप हेडर और बॉडी में अपनी इच्छानुसार कुछ भी भेज सकते हैं। लेकिन, अगर दोनों मेल नहीं खाते हैं, तो आपको गलत परिणाम मिल सकते हैं। यदि आप हेडर में निर्दिष्ट करते हैं कि सामग्री यूटीएफ -8 एन्कोडेड है, लेकिन आप वास्तव में लैटिन 1 एनकोडेड सामग्री भेज रहे हैं, तो रिसीवर कचरा डेटा का उत्पादन कर सकता है, लैटिन 1 एनकोडेड डेटा को यूटीएफ -8 के रूप में व्याख्या करने की कोशिश कर रहा है। यदि निश्चित रूप से आप निर्दिष्ट करते हैं कि आप लैटिन 1 एनकोडेड डेटा भेज रहे हैं और आप वास्तव में ऐसा कर रहे हैं, तो हाँ, आप उन 256 वर्णों तक सीमित हैं जिन्हें आप लैटिन 1 में एन्कोड कर सकते हैं।


4
बेशक, JSON में आप अभी भी गैर-लैटिन 1 वर्णों का प्रतिनिधित्व कर सकते हैं जैसे भागने के दृश्यों का उपयोग करना \u20AC
dan04

31
Json के लिए मानक के अनुसार, आपको वास्तव में सामग्री के एन्कोडिंग के लिए लैटिन 1 का उपयोग करने की अनुमति नहीं है। JSON सामग्री को यूनिकोड के रूप में एन्कोड किया जाना चाहिए, यह UTF-8, UTF-16, या UTF-32 (बड़ा या छोटा एंडियन) हो।
डैनियल लूना

20
आवेदन / json पर कोई चारसेट पैरामीटर नहीं है।
जूलियन रेसके ने

7
@DanielLuna सही है, application/jsonucs परिवर्तन प्रारूपों में से एक में होना चाहिए। इसके अलावा, चूंकि JSON के पहले चार बाइट्स सीमित हैं, आप हमेशा बता सकते हैं कि यह 8, 16 या 32 है और इसका एंडियन-नेस है।
जेसन कोको

4
घटना अगर यह बेमानी है तो आप charset=utf-8सुरक्षा कारणों से शामिल करना चाहते हैं : github.com/shieldfy/API-Security-Checklist/issues/25
manuc66

143

@ धोखे के दावे को प्रमाणित करने के लिए कि डिफ़ॉल्ट JSON एन्कोडिंग UTF-8 है ...

से IETF RFC4627 :

JSON टेक्स्ट SHALL को यूनिकोड में एन्कोड किया जाएगा। डिफ़ॉल्ट एन्कोडिंग UTF-8 है।

चूंकि JSON टेक्स्ट के पहले दो अक्षर हमेशा ASCII वर्ण [RFC0020] होंगे, इसलिए यह निर्धारित करना संभव है कि क्या एक ऑक्टेट स्ट्रीम UTF-8, UTF-16 (BE या LE), या UTF-32 (BE या LE) है पहले चार सप्तक में नल के पैटर्न को देखकर।

      00 00 00 xx  UTF-32BE
      00 xx 00 xx  UTF-16BE
      xx 00 00 00  UTF-32LE
      xx 00 xx 00  UTF-16LE
      xx xx xx xx  UTF-8

12
यह हमेशा JSON के बारे में द्विआधारी प्रारूप के बारे में सोचने में मदद करता है, न कि पाठ प्रारूप।
सुल्तान

2
अब जब RFC4627 को RFC7159 द्वारा पालन किया गया है, जिसमें कहा गया है कि मूल मूल्य एक स्ट्रिंग हो सकता है (पूर्व कल्पना के विपरीत स्पष्ट रूप से), अब इसे कैसे लागू किया जाता है? इस संबंध में युक्ति अस्पष्ट है, और बस यह कहता है कि तीन एन्कोडिंग की अनुमति है, लेकिन यह नहीं है कि उन्हें कैसे अंतर करना चाहिए।
फाबियो बेल्ट्रामिनी

4
@FabioBeltramini उपरोक्त को अभी भी रोकना चाहिए, क्योंकि JSON में एक स्ट्रिंग में कोई शाब्दिक अशक्त वर्ण नहीं होंगे (JSON में नल को संख्यात्मक एस्केप अनुक्रम के साथ एन्कोडेड करने की आवश्यकता होगी "\u0000")।
थोमसट्रेटर

3
वास्तव में UTF-16xx में दूसरा वर्ण उस मामले में NULL नहीं हो सकता है, लेकिन फिर भी अन्य बाइट्स से एन्कोडिंग निर्धारित करना संभव होगा: xx 00 00 00अभी भी UTF-32LE है और xx 00 xx xxअभी भी UTF-16LE है, 00 xx xx xxअभी भी UTF-16BE है।
थोमसट्रेटर

20

ध्यान दें कि IETF RFC4627 ने ले लिया है IETF RFC7158 । खंड [it.१] में यह पहले कहे गए @ द्वारा उद्धृत पाठ को वापस लेता है:

Implementations MUST NOT add a byte order mark to the beginning of a JSON text.

यह धारणा अभी भी बरकरार है, क्योंकि कोई भी वैध जौन अब भी दो अस्सी चरित्रों के साथ शुरू होगा।
लार्सिंग

एक वर्ण, क्योंकि एक एकल अंक एक वैध JSON फ़ाइल है
Nayuki

0

मैं वास्तव में @ डिसेज़ से सहमत हूं, लेकिन मैं इसे "मुझे सेवा से एक त्रुटि मिलती है" प्रश्न का हिस्सा विकसित करना चाहता हूं ,

Http 415 के रूप में हमें इस तरह की त्रुटियां हो रही हैं

Http 415 असमर्थित मीडिया प्रकार त्रुटि

HTTP 415 असमर्थित मीडिया प्रकार क्लाइंट त्रुटि प्रतिक्रिया कोड इंगित करता है कि सर्वर अनुरोध को स्वीकार करने से इनकार करता है क्योंकि पेलोड प्रारूप एक असमर्थित प्रारूप में है।

प्रारूप समस्या अनुरोध के संकेतित सामग्री-प्रकार या सामग्री-एन्कोडिंग के कारण या सीधे डेटा का निरीक्षण करने के परिणामस्वरूप हो सकती है।

दूसरे शब्दों में जैसे कि https://stackoverflow.com/a/22643964/914284 इस उदाहरण में देखा गया है ।

  • हमें सही सामग्री प्रकार सेट करना होगा और हमें सही सामग्री प्रकार स्वीकार करना होगा जैसा कि सामग्री-प्रकार जोड़ें: एप्लिकेशन / json और स्वीकार करें: एप्लिकेशन / json। अन्यथा यह डिफ़ॉल्ट मान जाएगा

0

डार्ट http का कार्यान्वयन बाइट्स को उस "charset = utf-8" के लिए धन्यवाद देता है, इसलिए मुझे यकीन है कि कई कार्यान्वयन इस का समर्थन करते हैं, जब प्रतिक्रिया से बाइट्स पढ़ने के दौरान "लैटिन -1" फालबैक चारसेट से बचने के लिए। मेरे मामले में, मैं प्रतिक्रिया बॉडी स्ट्रिंग पर पूरी तरह से प्रारूप खो देता हूं, इसलिए मुझे अपने सर्वर की एपीआई प्रतिक्रिया पर उस हेडर "आंतरिक" पैरामीटर को मैन्युअल रूप से utf8 में बाइट्स एन्कोडिंग करना होगा, या जोड़ना होगा।


0

मैं HttpClient का उपयोग कर रहा था और सामग्री-प्रकार के साथ प्रतिक्रिया प्रतिक्रिया प्राप्त कर रहा था application/json, मैंने विदेशी भाषा या प्रतीक जैसे वर्ण खो दिए, जो कि HttpClient के बाद से यूनिकोड का उपयोग करता है, ISO-8859-1 के लिए डिफ़ॉल्ट है । इसलिए, किसी भी संभावित समस्या से बचने के लिए @WesternGun द्वारा बताए गए अनुसार संभव हो।

कोई रास्ता नहीं है कि सर्वर के कारण मेरे लिए अनुरोध-हेडरसेट ( method.setRequestHeader("accept-charset", "UTF-8");) को नहीं संभालता है और मुझे प्रतिक्रिया डेटा को बाइट के रूप में प्राप्त करना था और इसे UTF-8 का उपयोग करके स्ट्रिंग में परिवर्तित करना था। तो, यह स्पष्ट होने और डिफ़ॉल्ट मूल्य की धारणा से बचने के लिए अनुशंसित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.