【发布时间】:2021-06-14 21:19:42
【问题描述】:
我已经在一个项目中熟悉了 FabricJS。
我有一个扩展 fabric.Polyline 的自定义类。这个自定义类有很多自定义方法。我的问题是:当我序列化整个画布,然后用 loadFromJSON() 再次加载它时,自定义方法不再存在......
我注意到序列化前后的对象并不完全相同。事实上,我们可以看到,在序列化之后,myCustomClassMethod() 方法已经不在对象的__proto__ 中了:
我知道 loadFromJSON() 有一个 reviver() 用于重新添加事件侦听器的方法,但是我该如何重新添加方法呢? tutorials 说我需要添加一个 fromObject() 方法来保存/恢复对象,我尝试使用它但没有运气。
也可能是我的反序列化对象是“常规”对象,而不是 fabricjs 对象实例。但我还没有看到如何让它再次成为织物对象。
MRE 在下面。如您所见,如果在 画布重新加载之前调用该方法有效,但如果在之后调用该方法则无效。
// create a wrapper around native canvas element (with id="treeCanvas")
var canvas = new fabric.Canvas('treeCanvas', {
allowTouchScrolling: true,
});
// un-comment log below to inspect objects
canvas.on('mouse:up', function (e) {
if (e.target != null) {
//console.log(e.target);
}
});
// My TreeNode custom class
var TreeNode = fabric.util.createClass(fabric.Polyline, {
initialize: function (X, Y, armsArray, options) {
options || (options = {});
this.callSuper('initialize', options);
this.X = X;
this.Y = Y;
this.armsArray = armsArray;
this.set({ width: 160, height: 50, originX: 'center', originY: 'center' });
this.set({ left: this.X, top: this.Y, fill: 'rgba(255, 255, 255, 0)', stroke: 'black', selectable: true });
this.setCoords();
this.set({ pathOffset: { x: 0, y: 25 } });
for (point of this.armsArray) {
this.points.push({ x: point[0], y: point[1] });
this.points.push({ x: 0, y: 0 });
}
},
_render: function (ctx) {
this.callSuper('_render', ctx);
},
// this is the method that disappears after serializing
myCustomClassMethod: function () {
this.set({ stroke: 'green' });
canvas.renderAll();
}
});
// Adding an instance of my custom class to canvas
var node1 = new TreeNode(100, 100, [[-80, 50], [80, 50]], []);
canvas.add(node1);
canvas.renderAll();
// node1.myCustomClassMethod(); // method works before serializing + deserializing
var stringifiedCanvas = JSON.stringify(canvas);
canvas.loadFromJSON(stringifiedCanvas, canvas.renderAll.bind(canvas));
node1.myCustomClassMethod(); // method DOES NOT WORK anymore after deserializing
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
<div class="container">
<canvas id="treeCanvas" width="500" height="300"></canvas>
</div>
<script src="canvas.js"></script>
【问题讨论】:
-
只是一个想法,您是否考虑过允许方法反序列化和执行的安全风险? (可能会注入包含 xss 攻击的恶意代码)
-
@melchiar TY 发表评论。我真的不太了解那个TBH。如果我只是对我自己定义的方法进行序列化/反序列化,那还会有风险吗? (我不会反序列化“外部”JSON 文件,这就是我的意思)。
-
是的,应该没问题。只有当用户能够提交他们可能已经注入代码的序列化画布时,这才是一个问题。
标签: javascript fabricjs