Http POST printing and CORS

Due to a lot of recent questions about my blog on Http POST printing, I'm posting this notification about CORS. I've been doing a lot of research and testing to try and figure out how and why many people are having issues printing using the Javascript I posted.  Specifically they are getting an error from their browsers "Access-Control-Allow-Origin header not found".  This is a HTTP header element that the third party server (in this case the printer) needs to respond with in order for the browser to know it's OK to call on it if the originating web-server is different.  This security feature is called CORS.  On PC's, most browsers are throwing the error in the console, but still allowing the communication through to the printerThe browsers on OSx machines and Apple products in general are blocking the communications due to this security restriction.  I'm sorry to say I missed this in my testing of the sample code.

 

CORS is a fairly recent security standard. We are exploring our options for handling it. If you are having a specific use case where this seems to be a problem, please comment below or email me directly.  Please make sure to mention the OS, browser, and printer models you are using.  This is so Zebra can correctly prioritize this issue.

 

There are several ways around the problem.  If your website is local to the browsers and printers it will be serving, you can (as posted in a comment from Jan Schinacher to my original post) take the ip address and, on the server, open a TCP socket or Telnet session to port 9100 or 6101 and send the data directly to the printer.  This is my recommended option for local sites as it allows full bi-directional communication (you can check if the printer is in a good state to print).  If the site is hosted elsewhere, there are still a couple of options as I've mentioned in earlier posts.  You can create a Zebra Weblink server for your webserver.  You can create a browser extension. The security is less tight, so most of them I've found will allow the communication through.   If the issue is found on Zebra mobile devices (as in MC75A, or TC55) then you can use our new Enterprise Browser with it's built in printing API's.  Other mobile devices will likely need an app to handle the printing communications.  We have a partner, Arrowhead, that makes a nice iOS app called MobiPrint

 

I hope this helps, and again my apologies for posting code that does not work for everyone.  I'm going to leave it up as it still is useful many developers for now.

 

Robin West

Solution Architect

Zebra ISV and Global Partners Technical

Comments


Hi Kai,

The code I posted will work in Chrome and Firefox browsers for most Zebra printers including the GX430t if they are Wi-Fi or Ethernet connected.  It's easier to state which printers it won't work in:

Card printers

Kiosk printers other than KR403 (KR403 works)

ZQ110

EN220 and EN220II

I can't guarantee it will work in discontinued mobile printers or stationary printers discontinued more than 3 years ago. 


I have one question for the POST printing function:

Are all Zebra printer which has the wireless LAN enabled is qualified for the POST printing function?

Will the code you posted for the POST sample be working for all printers?

We recently get one GX430t but realized there is no wireless LAN in it, so we gonna get a new one with wireless enabled. Need some advice before we actually make the purchase.

Thanks


Hi Robert,

Unfortunately no, we have not updated the printers yet with this fix.  We do have some other options though, many of which are outlined in this document: ​  In your situation I would probably recommend the Web-Printing Driver as the closest fit.  If your clients are primarily using the same type of browser, like Chrome or Firefox, there might also be solutions like extensions that should work.


Thanks, that document looks like it has some good leads!

After all that, I bought a GK420d without the built-in print server (no ethernet port) so I'll have to try something other than that HTTP endpoint anyways.

Thanks again!

Robert


Hi, just wanted to check the status of this issue.

We want to support Zebra printers for our browser-based product. We won't have any servers -- just clients using their web browsers -- so using an intermediary webserver isn't an option for us.

Do any recent models include the "Access-Control-Allow-Origin" headers to enable CORS? Is it possible to upgrade printers that were already purchased?

I'd love to add support for your hardware. The printers are so good! We just need to satisfy the browser's security requirements!

Thanks,

Robert


Then the Web-Printing Driver is probably your best option as it does support USB as well as network.


Hello Robin,

First thank you for this post and the "Http Post Printing" one as well.

I am building an oracle Apex application for our company. We have centers in many countries and they all need to print using Zebra printers as well as normal thermal printers.

For Zebra, and because we have various types of printers, I went with the javascript solution.

first, I came across the CORS issue and since the printer is printing anyways, I ignored the error message.

Then I came across another issue, Some printers respond to:

http:// + ip_addr + /printer/pstprnt

And others to:

http:// + ip_addr + /pstprnt

So in my code I call both and one of them usually respond? do you have another suggestion?

Second, what about error handling? the printer is responding with an error anyways, so how can I tell?

Is there anyway I can verify the URL before sending the requests?

Last, on one of the sites, I can ping the printer, yet when I type the IP in the browser, I can`t open the configuration page -the printer is ZT 230-, do you have any suggestions on how I can trouble shoot that?

I am not sure what I can and can`t ask you, so please if any of those questions is not in your domain just ignore it, or kindly let me know where should I ask it.

Thanks.


Robin,

Have any plans been made to resolve this? I'm developing a B2B cloud solution be we're trying to minimize any presence on customer networks. I'd really like to use the HTTP post method, but I'm nervous that future browsers will break this by restricting this type of communication.


Hi Ryan,

Zebra product management is aware of the issue and evaluating the best course forward. Based on demand from our users we have developed several other ways to handle web based printing​ including the new Browser Print tool.   We are looking for feedback into what use cases our developers are using to influence the prioritization of new tools and features.


Hi Robin,

is there any update on this? Is there a new firmware for the printers, so the access-control-origin-header is set to accept data from any source?

We are working with the javascript solution for 1.5 years now and it is rock solid. We don't have additional software on the devices which trigger the label printing. And we have no problems what so ever.

However, I'm afraid that an automatic update of Google Chrome will break the entire installation.

Thanks for your update on this,

Jan


Hi Robin,

Does the Browser Print tool use HTTP POST, just like your other post (see: )? I am struggling to get Zebra printing working on a HTTPS server.

Thanks!


Hi Robin,

Thank you for your detailed explanation.

Our company uses the ZT410 model.

I'm sorry, but I do not know what to do if I read the explanation above.

Let me explain how we would like to use it.

1. SERVER (Not in the same network, not in our company, in another area.)

2. User PC

3. ZT410 connected to your PC

4. Router

SERVER - Router - User PC - Consists of ZT410 connected to user PC.

I want to print ZPL with ZT410 through CHROME browser connected to SERVER. The languages ​​we use are JAVA and JSP. TOMCAT and DATABASE are installed in SERVER.

When testing, install TOMCAT, JAVA, JSP on the user's PC, connect only DATABASE to the SERVER, and print the ZT410 connected to the user's PC.

However, the actual usage environment should be connected to the program of SERVER.

Please help me print this.

If there is a method or a sample source, it is better.

You will be busy too. I'm sorry, but I would appreciate it if you answer. ^^

I have tried for a long time, but it is too difficult because I have no achievements.

Please help me ..

(If English is strange, please understand.)

e-mail : mdis@mdis.co.kr


Hello,

I have same problems + https problem :

- CORS browser rejects a direct call

- call HTTP over HTTPS is not allowed

Solution i have implemented/tested :

1. use an intermediate server : often you are adding a "print" button in your web interface. You can call the printer via this server. Server side script does not checks CORS at all.
One problem is if your web server cannot contact your printer due to network segregation (printer in 192.168.x.x, server in the internet, and no way to communicate between them)

2. use web browser : latest fetch API allows for 'no-cors' request mode. This means no address checkup done for this request.

web api support : Fetch API - Web APIs | MDN

It works, but Fetch api is not available in IE (if someone still use it).

This solution is  not 'perfect' but works if you have network segregation (printer cannot be contacted by server) and your client know printer IP.

var request = new Request('http://192.168.2.2/printer/pstprnt',

  {

   method: 'POST',

   mode: 'no-cors',

   cache: 'no-cache',

   body: 'ZPL CODE'
  });

fetch(request)

  .then(function (response) {

   // Important : in 'no-cors' mode you are allowed to make a request but not to get a response
  // even if in 'Network' Tab in chrome you can actually see printer response
  // response.ok will always be FALSE and response.text() null
  /*if (!response.ok) {
  throw Error(response.statusText);
  }*/
   return true;

  })

  .catch(function (error) {

   // note : if printer address is wrong or printer not available, you will get a "Failed to fetch"
   console.log(error);

  });

3. HTTPS :

Currently printer is using only HTTP, since your website should be protected by default your client use HTTPS instead of HTTP.

You can use solution 1 if same network.

But if you are in network segregation you want to use solution 2. Problem : browser will not allow request to HTTP in an HTTPS website (Preventing Mixed Content  |  Web       |  Google Developers  ) : So in this last case there is no solution simple at the moment !


a solution could be : add a Raspberry pi (or whatever local server) to bridge printer in https.

It would be nice if Zebra printer could implement an HTTPS server, it means give the possibility to provide an url and a certificate.

Hope this help.


We apologize for the inconvenience. The Km.zebra.com site is back up now.


Dear Robin,

WE can not access Zebra Web Printing Solutions.


Hello, it appears the HTTPS might be supported now if you put an SSL certificate on the printer.

Programming Guide – Page 768 – ZQ520 has HTTPS capability

https://www.zebra.com/content/dam/zebra/manuals/en-us/software/zpl-zbi2-pm-en.pdf

Administration Guide -  Page 10, Page 48-50 – How to generate SSL certificate and place on printer

https://www.zebra.com/content/dam/zebra/utilities/en/configuration/printeradminstrationguide-rev11-a.pdf

You can go check your variables to see if you have ip.https.enable. If your printer is supported and you don't you may just need to download the lastest firmware.


Thanks Michael for pointing this out.  I'll verify this use case.  I do know the user supplied SSL cert functionality is new in Link-OS firmware.  I'll post the firmware version version that it was implemented in.


Hey Robin,

Just to confirm, yesterday we were able to print using your HTTP POST demo code from an HTTPS site. There have been a few issues with having to confirm the generated certificate from the client side, but it does print from HTTPS.

Hopefully this can help others in a similar situation.


I think browser updates are wreaking havoc.  This worked initially (a few months ago).

In our test environment we can print successfully from Firefox but not Chrome.  At a customer site that is a Mac environment, they cannot print from either.  The web pages are served up externally, so there might be a CORS issue.  I tried the CORS anywhere plugin for Firefox, but that has not helped.

But I cannot even get a response in the Mac environment. I can see the Browser Print listening on ports 9101 and 9100.  In a browser console, I can see the call to GET https://localhost:9101/default, and it shows the request headers, but the response headers are never returned.  I am guessing that Firefox is blocking the response altogether, but I cannot see why.  Can you point me in the right direction?

BTW, I was trying to download the Mac version of Browser Print again today, but the download page links to something different.


Hi ​,

I'm trying to use the zebra browser print and tried to integrate the code found in ZebraBrowserPrintDocsWebCodeExamples but I received an error "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:9101/default?type=printer. (Reason: CORS request did not succeed)."

I'm developing Salesforce visualforce page using the following

1. Firefox, Edge, Chrome browser

2. Windows OS (Laptop)

3. Zebra GK420t printer

Thanks,

Albino