5

I'd like to use array as data-* attribute and a lot of StackOverflow answers suggest that I should use JSON.stringify();

So, if I have this array: ['something', 'some\'thing', 'some"thing'] it will be parsed to "["something","some'thing","some\"thing"]" and therefore it won't fit neither data-*='' nor data-*="" because either ' or " will break the HTML tag.

Am I missing something or encodeURIComponent() is a true solution to encoding arrays like that? Why in other StackOverflow answers nobody noticed this?

Community
  • 1
  • 1
Jimsea
  • 585
  • 1
  • 6
  • 11
  • Do you want to generate HTML code _using_ JavaScript, or why are you asking about `encodeURIComponent` …? – CBroe Aug 16 '14 at 20:26
  • you can simply tack a property onto an element, including arrays. that would prevent complications from parsing html. – dandavis Aug 16 '14 at 21:26
  • 1
    No, I just want to put a value that uses both `"` and `'` as a value of a `data-*` attribute. – Jimsea Aug 16 '14 at 21:30

1 Answers1

6

The reasoning that JSON.stringify is not guaranteed to be safe in HTML attributes when the text is part of the HTML markup itself is valid. However, there is no escaping issue if using one of the access methods (eg. .data or .attr) to assign the value as these do not directly manipulate raw HTML text.

While encodeURIComponent would "work" as it escapes all the problematic characters, it both results in overly ugly values/markup and requires a manual decodeURIComponent step when consuming the values - yuck!

Instead, if inserting the data directly into the HTML, simply "html encode" the value and use the result as the attribute value. Such a function comes with most server-side languages, although an equivalent is not supplied natively with JavaScript.

Assuming the attribute values are quoted, the problematic characters that need to be replaced with the appropriate HTML entities are:

  • & - &, escape-the-escape, applied first
  • " - ", for double-quoted attribute
  • ' - ', for single-quoted attribute
  • Optional (required for XML): < and >

Using the above approach relies on the parsing of the HTML markup, and the automatic decoding of HTML entities therein, such that the actual (non-encoded) result is stored as the data-attribute value in the DOM.

clami219
  • 2,958
  • 1
  • 31
  • 45
user2864740
  • 60,010
  • 15
  • 145
  • 220
  • In case you need to display the JSON data in ` – Asuka165 Jun 13 '19 at 19:03
  • > simply "html encode" the value. Neglects to provide an example on how to do that. – AlxVallejo Mar 05 '20 at 18:47
  • @AlxVallejo The language/environment generating the JSON has not been specified. "_Such a function comes with most server-side languages_, .."; of which most can be found when searching. – user2864740 Mar 06 '20 at 00:28
  • @user2864740 ok, well you cited `encodeURIComponent` which is JavaScript. So what would you use instead? – AlxVallejo Mar 06 '20 at 00:41
  • `encodeURIComponent` was referenced by the original post so it warranted to be be mentioned specifically; per the answer, JavaScript has no such method defined (as per the ECMAScript specification or the W3C DOM), although one could find one of many 3rd-party libraries that do. Again, depends on context. – user2864740 Mar 06 '20 at 03:20
  • but what if you need to both access the attribute from javascript *and* from innerHTML? it seems no matter how I encode, I can't get *both* to work. – Michael Feb 25 '23 at 05:08