PDA

View Full Version : EXTJS 4.1 chart save: from:http://svg.sencha.io security issue



ananthk
23 Jul 2012, 9:32 AM
When we try to save the chart it sends the message over to http://svg.sencha.org. For security reasons we cannot use this. Also what if it is a private network and this functionality need to work. Is there any way work around this? This is really cool. But please make it usable and help!

scottmartin
23 Jul 2012, 11:27 AM
Have a look at:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.draw.engine.ImageExporter-property-defaultUrl

Scott.

ananthk
23 Jul 2012, 11:49 AM
Thanks for the reply. definitely there is a clue here. But how do I override this? I have to think about this. Is there a resolved solution for this already?

performChart.save({
type: 'image/png'
});

scottmartin
23 Jul 2012, 12:00 PM
Have you tried:



Ext.draw.engine.ImageExporter({ defaultUrl: 'newURL' });
performChart.save({ .. });


Scott.

ananthk
23 Jul 2012, 1:13 PM
No it did not work. Is seems to be using some service to really draw the image. I changed my address and it did not work. I put it back http;//svg.sencha.io it works again. I also tried changing the url here in ImageExporter and it did not work. Also it uses the method 'POST' here and I don't understand what is this doing?

ImageExporter.js
Ext.define('Ext.draw.engine.ImageExporter', {
singleton: true,

statics: (function(){
var exportTypes = {
"image/png": 1,
"image/jpeg": 1
},
init = function(config){

if(config.hasOwnProperty('width')){
width = config['width'];
}
if(config.hasOwnProperty('height')){
height = config['height'];
}
if(config.hasOwnProperty('type') && exportTypes[config['type']]){
type = config['type'];
}else{
return false;
}

// if all the elements were set up before
// we don't need to reset their values and reappend them to the form
if(formEl && svgEl && typeEl && widthEl && heightEl){
return true;
}

formEl = formEl || Ext.get(document.createElement('form'));
formEl.set({
action: 'MYURL',
method: 'POST'
});

svgEl = svgEl || Ext.get(document.createElement('input'));
svgEl.set({
name: 'svg',
type: 'hidden'
});

typeEl = typeEl || Ext.get(document.createElement('input'));
typeEl.set({
name: 'type',
type: 'hidden'
});
widthEl = widthEl || Ext.get(document.createElement('input'));
widthEl.set({
name: 'width',
type: 'hidden'
});
heightEl = heightEl || Ext.get(document.createElement('input'));
heightEl.set({
name: 'height',
type: 'hidden'
});

formEl.appendChild(svgEl);
formEl.appendChild(typeEl);
formEl.appendChild(widthEl);
formEl.appendChild(heightEl);

Ext.getBody().appendChild(formEl);

return true;
},
process = function(surface){


var svgString = Ext.draw.engine.SvgExporter.self.generate({}, surface);


widthEl.set({
value: width || surface.width
});

heightEl.set({
value: height || surface.height
});

if(type){
typeEl.set({
value: type
});
}
svgEl.set({
value: svgString
});

formEl.dom.submit();

},
formEl, typeEl, svgEl, widthEl, heightEl, type, width, height;


return {
generate: function(config, surface){
if(init(config)){
process(surface);
}else{
return false;
}
}
};
}())


});

evant
23 Jul 2012, 1:16 PM
Yes, that's what the service does. From the docs:



To do this, the svg string must be sent to a remote server and processed.


If you're pointing it at your own server, you need to process the SVG string and turn it into an image.

ananthk
23 Jul 2012, 1:29 PM
Not sure How I do that? Is there any example? I would like to make this work.

evant
23 Jul 2012, 1:31 PM
You'll need to find an example in whatever server language you use, it's not a client problem.

ananthk
23 Jul 2012, 1:38 PM
OK. Is there any opens source package that can be installed in place of sencha service?

scottmartin
23 Jul 2012, 1:40 PM
What is your server side language? As mentioned, you will need to research this based on that.

Scott.

ananthk
23 Jul 2012, 1:43 PM
JAVA on a linux o/s. Any idea?

evant
23 Jul 2012, 1:53 PM
First google result: http://stackoverflow.com/questions/8167977/how-to-convert-svg-into-png-on-the-fly

Please take some time to research this yourself, we aren't your personal search engine.

ananthk
23 Jul 2012, 2:00 PM
Thanks. Did not help the situation for now. It was really unexpected that Sencha used their own server side mechanism to convert the SVG string to the images. Of course it is quoted in the docs. But still did not understand the purpose of this. No body likes the functionality if it is not secure.

Rein
27 Jul 2012, 5:18 AM
Did you tried to set url directly? Like this: Ext.draw.engine.ImageExporter.defaultUrl = "http://yourdomain.com/"; chart.save({ type: 'image/png' });

ferreol.robert
26 Oct 2012, 12:19 PM
You must create on your server side a transformer from svg to image.

http://yoursite/transformer with parameter image=your svg image

In javascript use https://github.com/aheckmann/gm

ralscha
1 Nov 2012, 1:16 AM
Here is a simple svg to png converter in Java. With the help of Apache Batik (http://xmlgraphics.apache.org/batik/) this was very easy to implement:



response.setContentType("image/png");
response.setHeader("Content-Disposition", "attachment; filename=\"mixedchart.png\";");


String svg = request.getParameter("svg");


StringReader stringReader = new StringReader(svg);
TranscoderInput input = new TranscoderInput(stringReader);


OutputStream out = response.getOutputStream();
TranscoderOutput output = new TranscoderOutput(out);


PNGTranscoder t = new PNGTranscoder();
try {
t.transcode(input, output);
} catch (TranscoderException e) {
throw new ServletException(e);
}


stringReader.close();
out.close();


The whole project is on GitHub: https://github.com/ralscha/playground/tree/master/svg2img
See the example in action: http://e4ds.rasc.ch/svg2img/


(http://e4ds.rasc.ch/svg2img/)

ngrover
17 Dec 2012, 8:52 AM
I put together a short how-to using Java/Batik: http://i4s.ca/code/sencha-svg.html

gary.bake
4 Jun 2013, 8:19 AM
You can render the SVG to a canvas element and then using toDataURL to export the canvas as a png in a new window.

First you need to add the canvg libraries https://code.google.com/p/canvg/
You need a canvas element hidden somewhere for it to work with an id of 'gbcanvas'


{
xtype:'button',
text: 'Print',
handler: function(btn) {
var chart = Ext.ComponentQuery.query('MyChart')[0];
var chartsvg = chart.save({type: 'image/svg+xml'});
var canvas = document.getElementById("gbcanvas");
canvg(canvas, chartsvg);
window.open(canvas.toDataURL("image/png"), '_blank');
}
},

I'm not sure what browser support is like and the renderings aren't exactly like the original image but everything is done in the client side.

gary.bake
5 Jun 2013, 4:15 AM
Canvg wasn't producing decent enough results so I've had a look and I can get the chart rendered to a canvas element but now I'm getting 'SecurityError: DOM Exception 18' when toDataURL is called on the canvas.

Looking around and this is caused by loading cross domain images but the canvas is being generated in the client so I'm not sure why it should fail?


var canvas = document.getElementById("gbcanvas");
var ctx = canvas.getContext("2d");
var chart = Ext.ComponentQuery.query('MyChart')[0];
var data = chart.save({type: 'image/svg+xml'});
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);


img.src = url;
img.onload = function() {
ctx.drawImage(img, 0, 0);
window.open(canvas.toDataURL("image/png"), '_blank');
};

Daniil
27 Feb 2014, 10:25 PM
We have created our own endpoint as an alternative of "svg.sencha.io".

The only thing required to use it is this piece of JavaScript code:

Ext.draw.engine.ImageExporter.defaultUrl = "http://svg.ext.net";

More details are here:
http://forums.ext.net/showthread.php?28195