JSON को HTML विशेषता में संग्रहीत करने का सबसे अच्छा तरीका है?


112

मुझे HTML तत्व पर एक JSON ऑब्जेक्ट को एक विशेषता में डालने की आवश्यकता है।

  1. HTML को मान्य नहीं करना है।

    क्वेंटिन द्वारा उत्तर दिया गया: JSON को एक data-*विशेषता में संग्रहीत करें , जो HTML5 मान्य है।

  2. JSON ऑब्जेक्ट किसी भी आकार का हो सकता है - यानी विशाल

    Maiku Mori द्वारा उत्तर दिया गया: HTML विशेषता की सीमा संभावित रूप से 65536 वर्ण है

  3. क्या होगा यदि JSON में विशेष वर्ण हैं? जैसे {foo: '<"bar/>'}

    क्वेंटिन द्वारा उत्तर दिया गया: सामान्य सम्मेलनों के अनुसार, विशेषता में डालने से पहले JSON स्ट्रिंग को एनकोड करें। PHP के लिए, फ़ंक्शन का उपयोग करें htmlentities()


EDIT - PHP और jQuery का उपयोग करके उदाहरण समाधान

HTML विशेषता में JSON लिखना:

<?php
    $data = array(
        '1' => 'test',
        'foo' => '<"bar/>'
    );
    $json = json_encode($data);
?>

<a href="#" data-json="<?php echo htmlentities($json, ENT_QUOTES, 'UTF-8'); ?>">CLICK ME</a>

JSON का उपयोग करके JSON को पुनः प्राप्त करना:

$('a').click(function() {

    // Read the contents of the attribute (returns a string)
    var data = $(this).data('json');

    // Parse the string back into a proper JSON object
    var json = $.parseJSON($(this).data('json'));

    // Object now available
    console.log(json.foo);

});

आप संभावित रूप से समझाएं कि क्यों और अलग-अलग समाधान के लिए पूछना चाहिए क्योंकि मुझे यकीन है कि यह सबसे अच्छा नहीं है। आप डेटा-कुछ विशेषताओं का उपयोग कर सकते हैं, लेकिन मुझे यकीन नहीं है कि वे पाठ की "विशाल" राशि पकड़ सकते हैं। विशेष वर्णों के लिए आप केवल पाठ से बच सकते हैं (बच सकते हैं) और unescape ())।
मायकू मोरी

हाँ सीमा 65536 वर्ण ( stackoverflow.com/questions/2752457/… )
Maiku Mori

1
Btw, यदि आपकी विशेषता का नाम है data-jsonतो आपको इसका उपयोग करना चाहिए $(this).data('json'), jQuery ने आपको उस हिस्से पर कवर किया है।
19

सिर्फ एक नोट, डेटा-प्रत्यय का नामकरण करने के लिए आवश्यक नहीं है। यदि आप किसी भी डेटा- custom_attribute में मान्य json डालते हैं तो यह jQuery के साथ ठीक काम करेगा।
गार्ट क्लैबोर्न

कृपया ब्रेसिज़ अनुक्रम को ठीक करें)}; =>});
MotsManish

जवाबों:


41

HTML को मान्य नहीं करना है।

क्यों नहीं? सत्यापन वास्तव में आसान क्यूए है जो बहुत सारी गलतियों को पकड़ता है। HTML 5 data-*विशेषता का उपयोग करें ।

JSON ऑब्जेक्ट किसी भी आकार (यानी विशाल) हो सकता है।

मैंने आकार की विशेषता के लिए ब्राउज़र की सीमाओं पर कोई दस्तावेज़ नहीं देखा है।

यदि आप उनमें भाग लेते हैं, तो डेटा को एक में संग्रहीत करें <script>idउस ऑब्जेक्ट में संपत्ति के नामों के लिए एक ऑब्जेक्ट और मैप एलिमेंट को परिभाषित करें ।

क्या होगा यदि JSON में विशेष वर्ण हैं? (उदा {परीक्षण: '<"myString />'})

विशेषता मानों में अविश्वसनीय डेटा शामिल करने के लिए सामान्य नियमों का पालन करें। का प्रयोग करें &amp;और &quot;(आप दोहरे उद्धरण में विशेषता मान लपेटकर कर रहे हैं) या &#x27;(अगर आपका रैपिंग एकल उद्धरण में विशेषता मान)।

ध्यान दें, हालांकि, यह JSON नहीं है (जिसमें यह आवश्यक है कि संपत्ति के नाम तार हों और तार केवल दोहरे उद्धरणों के साथ सीमांकित किए जाएं)।


5
तो आप कह रहे हैं कि मुझे htmlentities($json)HTML विशेषता में डालने से पहले मुझे क्या करना चाहिए ? और फिर मैं इसे कैसे डीकोड करूं जब मैं इसे jQuery में पढ़ना चाहता हूं? और फिर मैं इसे jQuery का उपयोग करके उसी तरह से कैसे लिखूं जिस तरह यह PHP में था?
BadHorsie

6
तो आप कह रहे हैं कि मुझे HTML विशेषता में डालने से पहले मुझे html_encode ($ json) करना चाहिए? - यदि आप PHP का उपयोग कर रहे हैं, तो वह काम करेगा। और फिर मैं इसे कैसे डीकोड करूं जब मैं इसे jQuery में पढ़ना चाहता हूं? - विशेषता से डिकोड? ब्राउज़र ऐसा करेगा जब वह HTML को DOM में पार्स करेगा। और फिर मैं इसे jQuery का उपयोग करके उसी तरह से कैसे लिखूं जिस तरह यह PHP में था? - आप DOM nodes की विशेषताएँ सेट कर रहे हैं, कच्चा HTML जेनरेट नहीं कर रहे हैं, ब्राउज़र इसका ध्यान रखेगा।
क्वेंटिन

1
जिस समय मेरे पास एक समस्या है, जहां मेरा ब्राउज़र वर्तमान में Google Chrome पर इसे डिकोड नहीं कर रहा है, और जब मैं JSON को पार्स करने जाता हूं तो सभी HTML इकाइयां वहां होती हैं और विफल हो जाती हैं।
ब्रैडली वेस्टन 12

यदि आप इसे स्क्रिप्ट टैग में रखते हैं, तो आपको स्क्रिप्ट टैग की विशेष हैंडलिंग के कारण इसे अलग तरह से बचना होगा। उदाहरण के साथ इसमें </ script> का मान स्क्रिप्ट टैग को समाप्त कर देगा।
डोबेस वांडरमेर

16

निर्भर करता है कि आपने इसे कहां रखा है,

  • में एक <div>के रूप में आप से पूछा, आप यह सुनिश्चित करें कि JSON एचटीएमएल विशेष है कि एक टैग, एचटीएमएल टिप्पणी, एम्बेडेड doctype शुरू कर सकता है शामिल नहीं है की जरूरत है, आदि आप कम से कम से बचने के लिए की जरूरत है <, और &है कि मूल चरित्र नहीं है इस तरह से भाग निकले अनुक्रम में दिखाई देते हैं।
  • में <script>तत्वों आप यह सुनिश्चित करें कि JSON समाप्त टैग नहीं होता की जरूरत है </script>: या भागने पाठ सीमा <!--या -->
  • ईवेंट हैंडलर में आपको यह सुनिश्चित करने की आवश्यकता है कि JSON इसका अर्थ सुरक्षित रखता है, भले ही इसमें ऐसी चीजें हों जो HTML संस्थाओं की तरह दिखती हैं और विशेषता सीमाओं ( "या ') को नहीं तोड़ती हैं ।

पहले दो मामलों के लिए (और पुराने JSON पार्सरों के लिए) आपको U + 2028 और U + 2029 को एनकोड करना चाहिए क्योंकि वे जावास्क्रिप्ट में newline वर्ण हैं, भले ही उन्हें JSON में अनएन्कोडेड स्ट्रिंग्स में अनुमति दी गई हो।

शुद्धता के लिए, आपको भागने की जरूरत है \और JSON पात्रों को उद्धृत करता है और यह हमेशा एनयूएल को एनकोड करने के लिए एक बुरा विचार नहीं है।

अगर HTML को बिना कंटेंट एन्कोडिंग के परोसा जा सकता है, तो आपको UTF-7 हमलों+ को रोकने के लिए सांकेतिक शब्दों में बदलना चाहिए ।

किसी भी मामले में, निम्नलिखित भागने तालिका काम करेगी:

  • एनयूएल -> \u0000
  • सीआर -> \nया\u000a
  • LF -> \rया\u000d
  • " -> \u0022
  • & -> \u0026
  • ' -> \u0027
  • + -> \u002b
  • /-> \/या\u002f
  • < -> \u003c
  • > -> \u003e
  • \-> \\या\u005c
  • U + 2028 ->\u2028
  • U + 2029 -> \u2029

तो Hello, <World>!अंत में एक नई पंक्ति के साथ पाठ के लिए JSON स्ट्रिंग मान होगा "Hello, \u003cWorld\u003e!\r\n"


1
return (input.replace(/([\s"'& + \ / \\ <> \ u2028 \ u2029 \ u0000]) / जी, (मैच, पी 1) => {वापसी \\u${p1.codePointAt(0).toString(16).padStart(4, 0)}; })); `
डेनिस गिफेलर

14

दूसरा तरीका आप इसे कर सकते हैं - जावास्क्रिप्ट डेटा को <script>टैग के अंदर रखा जाता है type="text/javascript", लेकिन जावास्क्रिप्ट निष्पादन से बचने के लिए , लेकिन इसके साथ type="text/bootstrap"या type="text/json"प्रकार के साथ नहीं ।

फिर, अपने कार्यक्रम के किसी स्थान पर, आप इसे इस तरह से पूछ सकते हैं:

function getData(key) {
  try {
    return JSON.parse($('script[type="text/json"]#' + key).text());
  } catch (err) { // if we have not valid json or dont have it
    return null;
  } 
}

सर्वर साइड पर, आप ऐसा कुछ कर सकते हैं (php और ट्विग के साथ यह उदाहरण ):

<script id="my_model" type="text/json">
  {{ my_model|json_encode()|raw }}
</script>

1
JSON के लिए स्क्रिप्ट प्रकार "एप्लिकेशन / json" का उपयोग करें। लंबे समय में किसी वस्तु के रूप में शीर्ष स्तर का होना अच्छा है।
OIS

1
यह सीधे ऑप के सवाल का जवाब नहीं देता है, लेकिन यह अभी भी मेरे लिए बहुत उपयोगी था। जो डेटा मैं स्टोर कर रहा हूं, वह पूरे पृष्ठ पर लागू होता है और किसी विशिष्ट तत्व के लिए नहीं, इसलिए एक तत्व विशेषता वास्तव में काम नहीं करती है (जब तक कि मैं इसे शरीर के तत्व पर पसंद नहीं करता हूं, जो विशेष रूप से मेरे लिए थोड़े लंगड़ा लगता है डेटा बड़ा हो सकता है)। इसे <script type="application/json" id="MyData"></script>पूरी तरह से काम करता है। फिर, ActiveWAFL / DblEj का उपयोग करके, मैं इसे देख सकता हूं document.GetData("#MyData"):।
इवान डे ला क्रूज़

2
इस उत्तर में गलत / खतरनाक जानकारी है! स्क्रिप्ट प्रकार बदलने से </ script> टैग का पता लगाना संशोधित नहीं होता है। बस कोशिश करें:<script type="application/json" id="MyData"> "abc</script><script>alert()</script>" </script>
हाइपरनोट

12

एक अन्य विकल्प बेस64 को JSON स्ट्रिंग को एनकोड करना है और यदि आपको इसे अपनी जावास्क्रिप्ट में उपयोग करने की आवश्यकता है, तो इसे atob()फ़ंक्शन के साथ डिकोड करें ।

var data = JSON.parse(atob(base64EncodedJSON));

के लिए धन्यवाद atob। मुझे उस बारे में कभी पता नहीं था!
इवेदी ओकोंकोव

3
खबरदार - काम नहीं करता है अगर JSON में गैर लैटिन वर्ण हैं।
रिएक्टर

5

आप नॉकआउट का उपयोग कर सकते हैं,

<p>First name: <strong data-bind="text: firstName" >todo</strong></p>
<p>Last name: <strong data-bind="text: lastName">todo</strong></p>

knockout.js

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
    this.firstName = "Jayson";
    this.lastName = "Monterroso";
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());

उत्पादन

पहला नाम: जैसन अंतिम नाम: मॉन्ट्रोसो

इसे देखें: http://learn.knockoutjs.com/


2

यहां कुछ भी नहीं फैंसी। PHP से, JSON स्ट्रिंग को रन के माध्यम htmlspecialcharsसे यह सुनिश्चित करने के लिए दें कि कोई विशेष वर्ण HTML के रूप में व्याख्या नहीं किया जा सकता है। जावास्क्रिप्ट से, कोई आवश्यक बचने; बस विशेषता सेट करें और आप जाने के लिए अच्छे हैं।


2

सरल JSON ऑब्जेक्ट्स के लिए, नीचे दिया गया कोड काम करेगा।

एनकोड:

var jsonObject = { numCells: 5, cellWidth: 1242 };
var attributeString = escape(JSON.stringify(jsonObject));

डिकोड:

var jsonString = unescape(attributeString);
var jsonObject = JSON.parse(jsonString);

1

आप क्या कर सकते हैं अपने तत्व के आसपास cdata का उपयोग करें / इस तरह

<![CDATA[  <div class='log' mydata='${aL.logData}'>${aL.logMessage}</div>     ]]>  

जहां mydata एक कच्चे जौन स्ट्रिंग है। आशा है कि यह आपकी और दूसरों की मदद करता है।


यह (समाधान) कैसे काम कर सकता है? क्या होगा अगर मैं ">mydata में कुछ स्टोर करना चाहता हूं ?
मार्टिन पीका

1
क्या होगा अगर स्ट्रिंग में "]]>" "
डोबेस वंडर्मर

1

एक और सोचा कि इस्तेमाल किया जा सकता विशेषता में एक बेस 64 स्ट्रिंग के रूप में JSON डेटा की दुकान और फिर उपयोग कर रहा है window.atobया window.btoaप्रयोग करने योग्य JSON डेटा करने के लिए इसे बहाल करने के लिए।

<?php
$json = array("data"=>"Some json data thing");
echo "<div data-json=\"".base64_encode(json_encode($json))."\"></div>";
?>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.