Best way to print binary (raw) ZPL data using QZ Tray?

1,326 views
Skip to first unread message

natha...@gmail.com

unread,
Jun 21, 2015, 5:57:44 PM6/21/15
to qz-p...@googlegroups.com
I need to print UPS and USPS shipping labels from the browser. I've been using the old jZebra applet and am trying to transition to QZ Tray.

When using the applet, I would save the ZPL data (which contains binary data) returned from my shipping vendor to a file, then use the appendFile() function to print the file.

I'm wondering if there's a better way to do this. Specifically, I'd prefer to avoid having to save the data to a file. I would much prefer to return the data via an AJAX request and then pass the data to QZ Tray, but I'm not sure how to do this.

I don't think JSON supports binary data, so I can base 64 encode the data in my PHP code and return that in the AJAX response, but I don't know how to get that to QZ Tray.

Do you have any suggestions?

Tres Finocchiaro

unread,
Jun 21, 2015, 8:28:39 PM6/21/15
to Nathan House, qz-p...@googlegroups.com

Yes, there are several methods which are better.  The $.ajax approach is the most straight forward.  Since the label contains binary data, the escaping can be an issue, even when using JSON for encoding, so the base64 approach is generally favored.

However, our appendFile function is asynchronous, so if you simply echo the label with a server-side language (e.g. php), Java can handle the rest without relying on $.ajax.  We've written appendFile to work with binary files, and the escaping issues generally aren't an issue in that case.  The code may look like this:

qz.appendFile("http://mydomain/raw.php?orderid=123456");

This is a very simple approach code-wise which will have the same asynchronous benefits associates with the $.ajax approaches you will find online.

The advantages to actually using $.ajax are that you would have the ability to loop over or modify the data prior to appending, which may have some benefits for manipulating the data just-in-time.

$.ajax also has the benefit in seeing the data prior to appending, if that is required on the JavaScript console.

Also, most label generators have base64 built-in, so if you do go that approach, simply use qz.append64("..."); and it will work just fine.

I hope that answers your question.

natha...@gmail.com

unread,
Jun 22, 2015, 11:47:20 AM6/22/15
to qz-p...@googlegroups.com, natha...@gmail.com
Thanks for the information, that's very helpful.

I need to use AJAX to request the data because errors are sometimes returned from my postage vendor, so I can't expect a script as shown in your example to always return a valid label.

A couple more questions:

1) I would suggest adding a way to disable debug output from qz-websocket.js. It outputs tons of info to the console which obscures my own output. I would still like errors to be output, of course.

2) I'm not very familiar with certificates and am still getting a popup dialog saying the site is untrusted when I try printing to QZ Tray.

I downloaded the private key and intermediate certs from this page: https://qz.io/get-certificate/

Then put the intermediate cert in getCertificate() and the private key in signRequest(). Here's my code:

function getCertificate(callback) {
$.ajax({
method: 'GET',
url: '/assets/misc/qztray-cert.x509',
async: false,
success: callback
});
}

function signRequest(toSign, callback) {
$.ajax({
method: 'GET',
// url: '/secure/url/for/sign-message.php?request=' + toSign,
url: '/assets/misc/qztray_rsa',
async: false,
success: callback
});

callback();
}

Did I do something wrong with the signRequest() function?

Thanks for all of your help,

Nate

natha...@gmail.com

unread,
Jun 22, 2015, 12:52:26 PM6/22/15
to qz-p...@googlegroups.com, natha...@gmail.com
Also, one thing I forgot to mention is that when shipping packages there is often more than one label returned. For example, international packages typically have 4-7 labels that have to be put in the pouch on the package. I'm assuming if I use the AJAX method I can return the labels in a JSON array and then just call print64() in a loop to print them all off.

Tres Finocchiaro

unread,
Jun 22, 2015, 7:33:01 PM6/22/15
to Nathan House, qz-p...@googlegroups.com
@Nathan,

Thanks for your email.  The getCertificate() code looks good, but the signRequest() is incorrect.  I think there is some confusion in general in terms of how the signing is performed.

> url: '/assets/misc/qztray_rsa',

For security reasons, we only support signing using a server-side language.  This server-side language can be PHP, Java (or a Java-based scripting language), C#, python, Ruby and several others.  The syntax that you should use would look like this:

> url: '/mysigningscript.php?request=' + toSign, // toSign = data to sign

The server-side code needs to load the private key and perform signing and echo the signature back.

We've provided several server-side examples in %programfiles%\QZ Tray\demo\assets\signing\ (or equivalent for your platform).

Some server-side languages are faster to setup than others.  We will continue to add examples as we assist more clients through this process.  If your server-side language is not there, we'll do what we can to help provide an example.

 there is often more than one label returned. For example, international packages typically have 4-7 labels that have to be put in the pouch on the package. I'm assuming if I use the AJAX method I can return the labels in a JSON array and then just call print64() in a loop to print them all off.

Correct, append64() can be called in succession (it is synchronous).  Alternately, if the data is returned as one long data stream you can simply append it at once.

Warning, if your labels spool over a certain amount (e.g. 50) you may want to use the advanced spooling features for your language per: https://github.com/qzind/qz-print/wiki/Raw-Printing#advanced-print-spooling

-Tres


--
You received this message because you are subscribed to the Google Groups "qz-print" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qz-print+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages