如何序列化和反序列化 JavaScript 对象?

Posted

技术标签:

【中文标题】如何序列化和反序列化 JavaScript 对象?【英文标题】:How to serialize & deserialize JavaScript objects? 【发布时间】:2011-04-06 05:33:07 【问题描述】:

我需要序列化和反序列化 javascript 对象以将它们存储在数据库中。

请注意,这些对象包含函数,所以我不能将它们存储为 JSON,所以我不能使用 json2.js。

JavaScript 对象的[反]序列化(当然是在 JavaScript 中)的最新技术是什么。

【问题讨论】:

如果 javascript 对象包含函数(即:方法),则无法在 JSON 中对它们进行编码。 JSON 只处理带有纯数据(散列、数组和原始类型)的 JS 对象。 具体来说:我需要存储来自 Google Maps Javascript API 的 DirectionsResult 对象。 DirectionsResult 包含 LatLng 对象,这些对象具有 JSON 无法处理的功能:code.google.com/apis/maps/documentation/javascript/… 我们不能将函数对象作为字符串存储在 json 中吗?? 我想序列化包含字符串的对象以通过 html 传递它们,允许所有字符。 JSON 禁止控制字符。我不需要序列化函数。有什么简短的功能吗? 【参考方案1】:

使用 gserializer

http://www.onegeek.com.au/articles/programming/javascript-serialization.php

google 中的代码:

http://code.google.com/p/gserializer/

GSerializer 是一个 JavaScript 库,用于 序列化/反序列化 javascript 对象往返于字符串,对于 比如说,一个 Cookie 的持久性。不像 许多其他实现, GSerializer 也可以序列化 函数和非 JSON 表示法。

【讨论】:

我早些时候遇到过,但我不确定该项目的成熟度。你个人用过吗? 看起来它不起作用:Gserializer TODO 说:“实现将参数传递到序列化函数(目前仅支持无参数函数)”,并且我必须序列化的对象包含函数参数(LatLng 对象上的 toUrlValue 函数:code.google.com/apis/maps/documentation/javascript/…)。还是谢谢! 对不起2,我希望他们完成这个项目 他已经一年没碰这个项目了。太糟糕了。我还需要带参数的函数【参考方案2】:

一般来说,(在浏览器中)无法序列化带有附加函数的对象:每个函数都有对其外部作用域的引用,当您反序列化它时该作用域将不存在,因此对该作用域的序列化引用将无效。

我要做的是使用带有replacerreviver 参数的内置(或json2.js)JSON.stringifyJSON.parse 函数。这是它如何工作的部分示例:

JSON.stringify(yourObject, function(name, value) 
    if (value instanceof LatLng)  // Could also check the name if you want
        return 'LatLng(' + value.lat() + ',' + value.lng() + ')';
    
    else if (...) 
        // Some other type that needs custom serialization
    
    else 
        return value;
    
);

JSON.parse(jsonString, function(name, value) 
    if (/^LatLng\(/.test(value))  // Checking the name would be safer
        var match = /LatLng\(([^,]+),([^,]+)\)/.exec(value);
        return new LatLng(match[1], match[2]);
    
    else if (...) 
        ...
    
    else 
        return value;
    
);

您可以在自定义类型中使用任何您想要的序列化格式。 “LatLng(纬度,经度)”格式只是其中一种方式。您甚至可以返回一个可以原生序列化为 JSON 的 JavaScript 对象。

【讨论】:

有趣。我阅读了 json2.js 文档(“排除了在 JSON 中没有表示的值(例如函数和未定义)。”)并假设没有在函数上调用替换器/恢复器函数。这段代码是你实际编写和使用的吗? @Stewart:这个想法是,当您反序列化它们时,您可以通过重新构造对象来避免序列化函数。 LatLng 构造函数将为您重新添加函数。替换器将在函数上工作,所以如果你真的想要,你可以尝试将函数转换为字符串。请注意,它并非在所有情况下都有效。 不处理字符串中的某些字符,例如换行符。【参考方案3】:

你不想序列化诸如函数之类的逻辑。

如果您将来必须更新您的逻辑/js 函数,您不(总是)希望旧的逻辑必须与数据一起加载。小心。

【讨论】:

【参考方案4】:

在 Node.js 上,还有 JASON package。

示例如下:

var JASON = require("JASON");

str = JASON.stringify(obj);
obj = JASON.parse(str);

通过npm install JASON安装包。

【讨论】:

【参考方案5】:

出于安全原因,我不会序列化 JS 函数。通过公共 API 可以将各种讨厌的东西发送到数据库。至于反序列化,我有不同的方法。我正在将客户端定义的模型对象与来自 JSON 的数据混合。我有一个小工具可以做到这一点,在 GitHub 上查看它khayll/jsonmix。

JsonMix 提供了一种从 JSON 反序列化为带有函数的 JavaScript 对象。

它看起来像:

//model definition (just an example)

var LatLng = function() 
LatLng.prototype.getMapTypeId = function() 
   return this.mapTypeId;


//deserializing done like this
var result = JSMix(jsonString).withObject(LatLng.prototype, "latLngs").build();

//all items in the latLngs collection have the functions coming from the model
console.log(result.latLngs[5].getMapTypeId());

【讨论】:

您能否解释一下为什么 序列化 Javascript 函数在任何情况下都可能存在安全风险? 如果您有一个公共 API,它接受包括功能在内的序列化 javascript 对象,并且在 Web 应用程序中使用。然后可以将恶意代码发送到您的服务器。假设您还在 Web 应用程序的某处读回这些对象并使用它们。现在,如果有人重写了该对象上的 toString() 函数,而您碰巧在代码中使用了它,那么有人可能会更改 Web 应用程序的预期功能。因此,当您从安全 URL 下载它时,该功能将不再受信任。 当然。但风险在于服务器的接受以及随后的反序列化和代码使用。序列化本身并不危险。 @fishgen Code Bling 是对的。更重要的是,没有必要假设他的用例或序列化的预期目的是你的。例如,他的目的可能是出于合规目的进行归档;以研究为导向;或任何数量的其他目的。【参考方案6】:

如果您使用的是 ES6 版本的 Node,您可以查看我编写的一个名为 JSOFF 的小包。它是 JavaScript 对象函数格式;处理函数的 JSON 的直接替代品。

它超级小而且简单,所以 Babeljs 或 Browserify 可能是你的朋友。

通过以下方式安装:npm install jsoffyarn add jsoff

以下是如何使用函数创建对象的示例:

const JSOFF  = require('jsoff');

var obj = 
  abc: 123,
  def: function (a,b)  return a * 2 + b * 3; ,
  ghi: a =>  return a * 2 ,
  jkl: (a,b) =>  return ((d,e) =>  return a*d + b*e )(2,4) 
;

var str = JSOFF.stringify(obj);
// str is now:  
// '"abc":123,"def":"function (a,b)  return a * 2 + b * 3; ","ghi":"a =>  return a * 2 ","jkl":"(a,b) =>  return ((d,e) =>  return a*d + b*e )(2,4) "');
);

var clone = JSOFF.parse(str);
clone.def(10,5)   // 35
clone.ghi(5)      // 10
clone.jkl(10,20)  // 100

【讨论】:

以上是关于如何序列化和反序列化 JavaScript 对象?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript二进制数据序列化和反序列化

JSON序列化

在C#中,Json的序列化和反序列化的几种方式总结

C#中如何实现多个观测数据对象序列化和反序列化?

delphi 编程中,如何对TStringlist对象进行序列化和反序列化呢? 哪位大虾能帮帮我啊,万分感激啊!!!

基于Json序列化和反序列化通用的封装