JavaScript JSON.parse “0x”字符串奇怪的转换

huangapple go评论101阅读模式
英文:

Javascript JSON.parse "0x" string strange conversion

问题

{
"data": {
"artemis_ids": {},
"symbols": {
"0XBTC": {
"price": 2.37
}
}
}
}

When I use JSON.parse in Google apps script, the "0XBTC" string is somehow converted to number 11. See below the results of console.log:

console.log("content", content);
console.log("content json", JSON.parse(content));

英文:

I have the following json structure returned by an API:

  1. {
  2. "data": {
  3. "artemis_ids": {},
  4. "symbols": {
  5. "0XBTC": {
  6. "price": 2.37
  7. }
  8. }
  9. }
  10. }

When I use JSON.parse in Google apps script, the "0XBTC" string is somehow converted to number 11. See below the results of console.log:

  1. console.log("content", content);
  2. console.log("content json", JSON.parse(content));

JavaScript JSON.parse “0x”字符串奇怪的转换

Any idea why this is happening and how to solve it?

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

  1. var content = `
  2. {
  3. &quot;data&quot;: {
  4. &quot;artemis_ids&quot;: {},
  5. &quot;symbols&quot;: {
  6. &quot;0XBTC&quot;: {
  7. &quot;price&quot;: 2.37
  8. }
  9. }
  10. }
  11. }
  12. `;
  13. console.log(&quot;content&quot;, content);
  14. console.log(&quot;content json&quot;, JSON.parse(content));

<!-- end snippet -->

答案1

得分: 2

以下是您要翻译的内容:

Modification points:

From content json {data={artemis_ids={}, symbols={11={price=2.37}}}}, your showing log, I guessed that you might disable the V8 runtime with the script editor. But, when the V8 runtime is disabled, the backticks cannot be used. From this situation, also I guessed that your showing snippet might not be your actual script.

By supposing that my guess is correct, I tested the following sample script. And, I disabled the V8 runtime with the script editor.

  1. function myFunction() {
  2. var content = '{ "data": { "artemis_ids": {}, "symbols": { "0XBTC": { "price": 2.37 } } } }';
  3. console.log("content", content);
  4. console.log("content json", JSON.parse(content));
  5. }

When this script is run without V8 runtime, the following result is obtained.

JavaScript JSON.parse “0x”字符串奇怪的转换

I confirmed that console.log("content json", JSON.parse(content)) shows content json {data={artemis_ids={}, symbols={11={price=2.37}}}}. If my guess is correct, I think that this might be the reason for your current issue.

And also, when I tested the following script.

  1. function sample() {
  2. var content = '{ "data": { "artemis_ids": {}, "symbols": { "0XBTC": { "price": 2.37 } } } }';
  3. var sample1 = JSON.stringify(JSON.parse(content));
  4. var sample2 = Object.keys(JSON.parse(content).data.symbols);
  5. console.log(sample1);
  6. console.log(sample2);
  7. }

console.log(sample1) and console.log(sample2) are as follows.

  1. { "data": { "artemis_ids": {}, "symbols": { "11": { "price": 2.37 } } } }

and

  1. [11]

From this situation, I guessed that this situation might be a bug or the current specification of Google Apps Script without V8 runtime. But, in the current stage, when the V8 runtime is disabled with the script editor, "runtimeVersion": "DEPRECATED_ES5" is added to the manifest file (appsscript.json). Ref

In order to avoid this situation, as a simple solution, please enable V8 runtime with the script editor. Ref

JavaScript JSON.parse “0x”字符串奇怪的转换

By this, the above script sample() returns as follows.

  1. { "data": { "artemis_ids": {}, "symbols": { "0XBTC": { "price": 2.37 } } } }

and

  1. [ '0XBTC' ]

0XBTC is correctly used as the key.

Note:

If you are required to use your script by disabling the V8 runtime, how about using polyfill of JSON.parse? Ref When this is reflected in a sample script, it becomes as follows.


  1. function sample2() {
  2. // Ref: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#%E3%83%9D%E3%83%AA%E3%83%95%E3%82%A3%E3%83%AB
  3. var rx_one = /^[\],:{}\s]*$/;
  4. var rx_two = /\\(?:[&quot;\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
  5. var rx_three = /&quot;[^&quot;\\\n\r]*&quot;|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
  6. var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
  7. var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  8. JSON.parse = function (text, reviver) {
  9. // The parse method takes a text and an optional reviver function, and returns
  10. // a JavaScript value if the text is a valid JSON text.
  11. var j;
  12. function walk(holder, key) {
  13. // The walk method is used to recursively walk the resulting structure so
  14. // that modifications can be made.
  15. var k;
  16. var v;
  17. var value = holder[key];
  18. if (value && typeof value === "object") {
  19. for (k in value) {
  20. if (Object.prototype.hasOwnProperty.call(value, k)) {
  21. v = walk(value, k);
  22. if (v !== undefined) {
  23. value[k] = v;
  24. } else {
  25. delete value[k];
  26. }
  27. }
  28. }
  29. }
  30. return reviver.call(holder, key, value);
  31. }
  32. // Parsing happens in four stages. In the first stage, we replace certain
  33. // Unicode characters with escape sequences. JavaScript handles many characters
  34. // incorrectly, either silently deleting them, or treating them as line endings.
  35. text = String(text);
  36. rx_dangerous.lastIndex = 0;
  37. if (rx_dangerous.test(text)) {
  38. text = text.replace(rx_dangerous, function (a) {
  39. return (
  40. "\\u" +
  41. ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
  42. );
  43. });
  44. }
  45. // In the second stage, we run the text against regular expressions that look
  46. // for non-JSON patterns. We are especially concerned with "()()()" and "new"
  47. // because they can cause invocation, and "=" because it can cause mutation.
  48. // But just to be safe, we want to reject all unexpected forms.
  49. // We split the second stage into 4 regexp operations in order to work around
  50. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  51. // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
  52. // replace all simple value tokens with "]" characters. Third, we delete all
  53. // open brackets that follow a colon or comma or that begin the text. Finally,
  54. // we look to see that the remaining characters are only whitespace or "]" or
  55. // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
  56. if (
  57. rx_one
英文:

Modification points:

From content json {data={artemis_ids={}, symbols={11={price=2.37}}}}, your showing log, I guessed that you might disable the V8 runtime with the script editor. But, when the V8 runtime is disabled, the backticks cannot be used. From this situation, also I guessed that your showing snippet might not be your actual script.

By supposing that my guess is correct, I tested the following sample script. And, I disabled the V8 runtime with the script editor.

  1. function myFunction() {
  2. var content = &#39;{&quot;data&quot;:{&quot;artemis_ids&quot;:{},&quot;symbols&quot;:{&quot;0XBTC&quot;:{&quot;price&quot;:2.37}}}}&#39;;
  3. console.log(&quot;content&quot;, content);
  4. console.log(&quot;content json&quot;, JSON.parse(content));
  5. }

When this script is run without V8 runtime, the following result is obtained.

JavaScript JSON.parse “0x”字符串奇怪的转换

I confirmed that console.log(&quot;content json&quot;, JSON.parse(content)) shows content json {data={artemis_ids={}, symbols={11={price=2.37}}}}. If my guess is correct, I think that this might be the reason for your current issue.

And also, when I tested the following script.

  1. function sample() {
  2. var content = &#39;{&quot;data&quot;:{&quot;artemis_ids&quot;:{},&quot;symbols&quot;:{&quot;0XBTC&quot;:{&quot;price&quot;:2.37}}}}&#39;;
  3. var sample1 = JSON.stringify(JSON.parse(content));
  4. var sample2 = Object.keys(JSON.parse(content).data.symbols);
  5. console.log(sample1);
  6. console.log(sample2);
  7. }

console.log(sample1) and console.log(sample2) are as follows.

  1. {&quot;data&quot;:{&quot;artemis_ids&quot;:{},&quot;symbols&quot;:{&quot;11&quot;:{&quot;price&quot;:2.37}}}}

and

  1. [11]

From this situation, I guessed that this situation might be a bug or the current specification of Google Apps Script without V8 runtime. But, in the current stage, when the V8 runtime is disabled with the script editor, &quot;runtimeVersion&quot;: &quot;DEPRECATED_ES5&quot; is added to the manifest file (appsscript.json). Ref

In order to avoid this situation, as a simple solution, please enable V8 runtime with the script editor. Ref

JavaScript JSON.parse “0x”字符串奇怪的转换

By this, the above script sample() returns as follows.

  1. {&quot;data&quot;:{&quot;artemis_ids&quot;:{},&quot;symbols&quot;:{&quot;0XBTC&quot;:{&quot;price&quot;:2.37}}}}

and

  1. [ &#39;0XBTC&#39; ]

0XBTC is correctly used as the key.

Note:

If you are required to use your script by disabling the V8 runtime, how about using polyfill of JSON.parse? Ref When this is reflected in a sample script, it becomes as follows.

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

  1. function sample2() {
  2. // Ref: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#%E3%83%9D%E3%83%AA%E3%83%95%E3%82%A3%E3%83%AB
  3. var rx_one = /^[\],:{}\s]*$/;
  4. var rx_two = /\\(?:[&quot;\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
  5. var rx_three = /&quot;[^&quot;\\\n\r]*&quot;|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
  6. var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
  7. var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  8. JSON.parse = function (text, reviver) {
  9. // The parse method takes a text and an optional reviver function, and returns
  10. // a JavaScript value if the text is a valid JSON text.
  11. var j;
  12. function walk(holder, key) {
  13. // The walk method is used to recursively walk the resulting structure so
  14. // that modifications can be made.
  15. var k;
  16. var v;
  17. var value = holder[key];
  18. if (value &amp;&amp; typeof value === &quot;object&quot;) {
  19. for (k in value) {
  20. if (Object.prototype.hasOwnProperty.call(value, k)) {
  21. v = walk(value, k);
  22. if (v !== undefined) {
  23. value[k] = v;
  24. } else {
  25. delete value[k];
  26. }
  27. }
  28. }
  29. }
  30. return reviver.call(holder, key, value);
  31. }
  32. // Parsing happens in four stages. In the first stage, we replace certain
  33. // Unicode characters with escape sequences. JavaScript handles many characters
  34. // incorrectly, either silently deleting them, or treating them as line endings.
  35. text = String(text);
  36. rx_dangerous.lastIndex = 0;
  37. if (rx_dangerous.test(text)) {
  38. text = text.replace(rx_dangerous, function (a) {
  39. return (
  40. &quot;\\u&quot; +
  41. (&quot;0000&quot; + a.charCodeAt(0).toString(16)).slice(-4)
  42. );
  43. });
  44. }
  45. // In the second stage, we run the text against regular expressions that look
  46. // for non-JSON patterns. We are especially concerned with &quot;()&quot; and &quot;new&quot;
  47. // because they can cause invocation, and &quot;=&quot; because it can cause mutation.
  48. // But just to be safe, we want to reject all unexpected forms.
  49. // We split the second stage into 4 regexp operations in order to work around
  50. // crippling inefficiencies in IE&#39;s and Safari&#39;s regexp engines. First we
  51. // replace the JSON backslash pairs with &quot;@&quot; (a non-JSON character). Second, we
  52. // replace all simple value tokens with &quot;]&quot; characters. Third, we delete all
  53. // open brackets that follow a colon or comma or that begin the text. Finally,
  54. // we look to see that the remaining characters are only whitespace or &quot;]&quot; or
  55. // &quot;,&quot; or &quot;:&quot; or &quot;{&quot; or &quot;}&quot;. If that is so, then the text is safe for eval.
  56. if (
  57. rx_one.test(
  58. text
  59. .replace(rx_two, &quot;@&quot;)
  60. .replace(rx_three, &quot;]&quot;)
  61. .replace(rx_four, &quot;&quot;)
  62. )
  63. ) {
  64. // In the third stage we use the eval function to compile the text into a
  65. // JavaScript structure. The &quot;{&quot; operator is subject to a syntactic ambiguity
  66. // in JavaScript: it can begin a block or an object literal. We wrap the text
  67. // in parens to eliminate the ambiguity.
  68. j = eval(&quot;(&quot; + text + &quot;)&quot;);
  69. // In the optional fourth stage, we recursively walk the new structure, passing
  70. // each name/value pair to a reviver function for possible transformation.
  71. return (typeof reviver === &quot;function&quot;) ?
  72. walk({
  73. &quot;&quot;: j
  74. }, &quot;&quot;) :
  75. j;
  76. }
  77. // If the text is not JSON parsable, then a SyntaxError is thrown.
  78. throw new SyntaxError(&quot;JSON.parse&quot;);
  79. };
  80. var content = &#39;{&quot;data&quot;:{&quot;artemis_ids&quot;:{},&quot;symbols&quot;:{&quot;0XBTC&quot;:{&quot;price&quot;:2.37}}}}&#39;;
  81. var sample1 = JSON.stringify(JSON.parse(content));
  82. var sample2 = Object.keys(JSON.parse(content).data.symbols);
  83. console.log(sample1); // &lt;--- {&quot;data&quot;:{&quot;artemis_ids&quot;:{},&quot;symbols&quot;:{&quot;0XBTC&quot;:{&quot;price&quot;:2.37}}}}
  84. console.log(sample2); // &lt;--- [0XBTC]
  85. }
  86. sample2();

<!-- end snippet -->

References:

答案2

得分: -1

我认为这不是一个代码问题,因为它在node@18和Chrome@latest上运行良好。

JavaScript JSON.parse “0x”字符串奇怪的转换

英文:

I think it is not a code issue, because it runs well at node@18 and Chrome@latest.

JavaScript JSON.parse “0x”字符串奇怪的转换

huangapple
  • 本文由 发表于 2023年7月27日 23:12:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76781148.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定