简体   繁体   中英

How to embed JSON in html?

I have a JSON array:

info = [{"name":"abc", "rank" : 1},{"name":"xyz", "rank":2},{"name":"pqr", "rank":3}];

and I am trying to pass it as an input value to a hidden field using jQuery and send it to the server with a POST request.

$('<form action="/info/saveAll" method="POST"/>')
        .append($('<input type="hidden" name="info" value="' + JSON.stringify(info) + '">'))
        .appendTo($(document.body))
        .submit();

At the server end, I am accessing the value of info as:

router.route('/saveAll')
    .post((req, res) => {
       let info = JSON.parse(req.body.info);
       console.log(info); //SyntaxError: Unexpected end of JSON input
    })

If I don't stringify the array before submit, then the typeof info still returns string inside the post and when I try to parse the string type I get syntax error like SyntaxError: Unexpected token o in JSON at position 1 .

I know this can be done by just doing it through an ajax post request, but I wanted a work around that does not involve an ajax request.

Any help would be great.

You can't simply concatenate a JSON string into HTML, because it can contain reserved characters, like " , that need to be quoted. Just comment out the .submit() and check the hidden input field your code added to the DOM with DOM Inspector in your browser developer tools. You'll see that the value= attribute is corrupted.

The solution is simple: use encodeURI() instead, ie

.append($(
    '<input type="hidden" name="info" value="' +
    encodeURI(JSON.stringify(info)             + 
    '\'>'))

and

let info = JSON.parse(decodeURI(req.body.info));

Now you'll see that the attribute is shown as valid JSON string in the DOM inspector. When you select "Edit as HTML" menu on your hidden input element you'll see a quoted string in the HTML text for the value= attribute.

From my manual test with Firefox:

Incorrect

const info = {
          test: "somestring",
          html: '<input type="hidden" value="&"/>',
      };
$('#demo').append($(
        '<input type="hidden" value="' +
        JSON.stringify(info))          +
        '">'));

The generated HTML:

<input type="hidden" value="{" test":"somestring","html":"<input="">

Correct

const info = {
          test: "somestring",
          html: '<input type="hidden" value="&"/>',
      };
$('#demo').append($(
        '<input type="hidden" value="'   +
        encodeURI(JSON.stringify(info))) +
        '">'));

The generated HTML:

<input type="hidden" value="%7B%22test%22:%22somestring%22,%22html%22:%22%3Cinput%20type=%5C%22hidden%5C%22%20value=%5C%22&amp;%5C%22/%3E%22%7D">

Another option is to use a HTML entities encode/decode method, f.ex. this SO question , but the provided answers seem to be more cumbersome than my solution. It would be easier to use a npm module instead, eg entities .


Or simply...

... don't rely on HTML string parsing and let jQuery do all the work. It also removes the need to use decodeURI() on the server side:

const info  = {
          test: "somestring",
          html: '<input type="hidden" value="&"/>',
      },
      input = $('<input type="hidden"/>')
          .val(JSON.stringify(info));
$('#demo')
      .append(input);

The generated HTML:

<input type="hidden" value="{&quot;test&quot;:&quot;somestring&quot;,&quot;html&quot;:&quot;<input type=\&quot;hidden\&quot; value=\&quot;&amp;\&quot;/>&quot;}">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM