2012-06-30 2 views
7

Я вижу, как я могу писать объекты в файлы, как описано здесь: How can I save objects to files in Node.js?, но есть ли способ взять объект и записать его таким образом, чтобы я мог перезагрузить объект в память, включая его методы?Запись объектов js в файлы (включая методы) в nodejs?

+2

Функции записи и чтения представляют огромный риск для инъекций. Я бы рассмотрел последствия этого решения для безопасности. –

+0

Я согласен с Энтони. Если вам это действительно нужно, вы можете просто сохранить код JavaScript, затем загрузить его и называть 'eval'. – freakish

+0

Я согласен с соображениями безопасности. Я просто играю с идеей. Благодаря! – luisgo

ответ

6

Как уже говорилось в @AnthonySottile, это может быть чрезвычайно опасно, и я не уверен, что для этого есть хороший вариант использования, но для пинков и хихиканья вам нужно будет написать собственный рекурсивный сериализатор. Что-то вроде этого:

var toString = Object.prototype.toString; 

function dump_object(obj) { 
    var buff, prop; 
    buff = []; 
    for (prop in obj) { 
     buff.push(dump_to_string(prop) + ': ' + dump_to_string(obj[prop])) 
    } 
    return '{' + buff.join(', ') + '}'; 
} 

function dump_array(arr) { 
    var buff, i, len; 
    buff = []; 
    for (i=0, len=arr.length; i<len; i++) { 
     buff.push(dump_to_string(arr[i])); 
    } 
    return '[' + buff.join(', ') + ']'; 
} 

function dump_to_string(obj) { 
    if (toString.call(obj) == '[object Function]') { 
     return obj.toString(); 
    } else if (toString.call(obj) == '[object Array]') { 
     return dump_array(obj); 
    } else if (toString.call(obj) == '[object String]') { 
     return '"' + obj.replace('"', '\\"') + '"'; 
    } else if (obj === Object(obj)) { 
     return dump_object(obj); 
    } 
    return obj.toString(); 
} 

Это будет работать с большинством типов, но всегда есть шанс на чудака Мессинг его так я бы не использовать это в производстве. После десериализации так же легко, как:

eval('var test = ' + dump_to_string(obj)) 
+3

O_O Почему вы изобретаете колесо? Определите метод 'toJSON' для пользовательской сериализации объекта, например. ' .prototype.toJSON'. Для большей гибкости определите [replacer для 'JSON.stringify'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify#Syntax). –

+0

@RobW Не знал об этом. Очень полезно, спасибо! – Trevor

+0

Очень полезно. Благодаря! – luisgo

0

Я недавно написал shovejs: http://shovemedia.github.com/shovejs/ обращаться именно такого рода вещи. YMMV - Я еще не пробовал его с узлом.

Он преобразует типизированную структуру объекта в JSON (которую вы затем сохранили на диск) и может надуть эту структуру обратно на типизированные объекты, включая правильный объект -> ссылки на объекты и т. Д. Чтобы быть ясным, сами определения метода/класса НЕ сериализованы. Система просто ожидает, что зарегистрированные классы Model/Factory, доступные во время сериализации, также доступны во время десериализации.

Извинения за то, что у вас не было простых примеров.

редактировать: техника является форсированным взять на себя то, что упоминает Rob W в своем комментарии ниже

1

Вопрос довольно старый, но я не мог найти где-нибудь какой-то простое решение вопроса об эффективной сериализации JavaScript.
Можно использовать BSON (представление внутренних объектов MongoDB), которое использует двоичный формат для представления объектов в памяти.

я не смог найти ссылку на документацию, но code is well documented и я придумал что-то вроде этого:

fs = require 'fs' 
bson = require('bson').BSONPure.BSON 

obj = { 
    string: "test", 
    func: (s) -> 
    console.log s 
} 

fs.writeFile 'test.txt', bson.serialize(obj, false, false, true), (err) -> 
    return console.log("Err : #{err}") if err 
    fs.readFile 'test.txt', (err, file) -> 
    return console.log("Err : #{err}") if err 
    deserialized = bson.deserialize file, evalFunctions: true 
    deserialized.func deserialized.string // Outputs 'text', as expected 

Это coffee-script но код достаточно прост для всех, чтобы понять.

+0

Осторожно с этой опцией 'evalFunctions: true', поскольку это позволит выполнить javascript (см. Https://gist.github.com/DinisCruz/245716893d783ea740ea) –

Смежные вопросы