Compress JSON sent to server

Hi,

I’m using angular2-signaturepad 2.4.0 to capture users signature and posting it to a Java REST server as part of a JSON object. The issue is that the signature are sometimes to big and the users get timeouts. Is there any way to compress the JSON prior to submitting it? I’ve tried using Pako to GZIP the JSON but for some reason the server code keeps telling me that it’s not a GZIP String

Ionic code:

        let body = JSON.stringify(data);
        let gzippedBody = Pako.gzip(body);
        let headers = new Headers({ "Content-Encoding" : "gzip"});
        headers.append('Content-Type', 'application/json; charset=x-user-defined-binary');
        let options = new RequestOptions({ headers: headers });
        return this.http.post(url, gzippedBody, options);

And on the server side (this is java/Spring code):

	@RequestMapping(value = "/save",method = RequestMethod.POST)
	@ResponseStatus(HttpStatus.OK)
	public ValidatorResult saveCancelledSessionNotes(@RequestBody String json ) throws JsonParseException, JsonMappingException, IOException
	{
		json = decompress(json.getBytes());
	}
	 public static String decompress(final byte[] compressed) throws IOException {
	        ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
	        GZIPInputStream gis = new GZIPInputStream(bis);
	        byte[] bytes = IOUtils.toByteArray(gis);
	        return new String(bytes, "UTF-8");
	}

And the error I get:

java.util.zip.ZipException: Not in GZIP format
	at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:165)
	at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
	at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)

I forgot to mention that I control both the client side and the server side. Meaning I don’t need to have the JSON GZipped it could be any compression format as long as I could decompress(inflate) on the server side in Java

As a side note, why does Ionic native zip only support unzipping? Why not implement some zipping logic? I would think that this is a common enough request

This probably isn’t going to be very helpful, but if you’re passing the signature as a PNG, it’s not going to compress any further. PNG already includes deflate compression.

Could you try resizing the image to smaller dimensions?

I’m passing it as a base64 string as part of a JSON along with more data. Compressing the images would help but I’m not even sure how to do that. I tried using https://github.com/agilgur5/trim-canvas but I don’t know how to use it

Is there no standard way of compressing strings in javascript? I don’t care which format of compression and I don’t care if it’s compressing the whole JSON or just specific parts of the JSON. Either way will get the job done

The fundamental problem is that the JSON format itself doesn’t allow binary data. You could try looking into ubjson.

I’m fine with submitting the signature as a request parameter submitted in a POST. The question is how do I compress the string? I thought that a simple question like compressing/zipping a string would have a simple solution but it seems like there isn’t.

There seem to be a bunch of JavaScript implementations of various compression algorithms. I haven’t used any of them, so can’t comment on quality. Still, I don’t think compression is going to help you, because of how the PNG format is already compressed. The best I think you can hope for is the encoding improvement offered by something like ubjson.

In the end I figured out how to use trim-canvas which should cut the image down significantly. Gzipping didn’t work and lz-string didn’t either. The only lz-string function that worked actually made the string longer after “compressing” it! That’s when I just gave up on the idea of zipping. Would still like to implement compressing the whole request/response but I don’t have more time to work on this

If anyone wants more details on the trim-canvas/signature stuff let me know and I’ll post it