williamkapke/ipp

Possibility to use it in Frontend JavaScript?

herom opened this issue · 21 comments

Hey,
I just came here 'cause I was looking for a solution to print from a web application directly to a (network) printer and it seems that IPP is the way to go. Unfortunately I'm not using Node.js as a backend and therefore I wonder if it's possible to use your library in the frontend as well? Would it be possible to pack it so that it could be installed through Bower or something like that?

Am I right that "the only thing you have to do" is to get a build tool like Grunt or something to pull in all files from the lib folder and compile it to one ipp.js file? If so, how would I set up Grunt to do this properly and build a file which I can use in the frontend as well?

Would be cool if you could give me some advice here as I'm really stuck at the moment :)

sorry for bumping @williamwicks but it would be very kind of you if you could give me some advice here...

Sry, Github didn't notify me of this post :/

IPP uses a custom binary message format- so the browser would need to be able to handle that. The next hurdle would be the network communication. ipp uses Node's built in http/https modules to make the network requests. Something would need to replace that (shim it? try to browserify it?). I would guess you'll get security errors trying to communicate across domains.

So, I won't say it is impossible- but I think it will certainly be challenging.

thanks a lot for the clarification, I'll look if I can take this further and bring it to the client.... challenging projects are the best :)

Hi @herom did you continue on this project?

@mzammit it's still on my TODOs list, as I'm working on another project which is taking my time to nearly 100%, but - as I said - it's still on my list. do you want to take part in creating a new project which takes care about this?

ipp uses Node's built in http/https modules to make the network requests. Something would need to replace that (shim it? try to browserify it?). I would guess you'll get security errors trying to communicate across domains.

There's a basic HTTP server for Firefox OS you can look at it's implementation to get the http/https modules replaced. Works only in newer Frefox by now (requires mozTCPSocket).

https://github.com/justindarc/fxos-web-server

There's also a Firefox OS telnet client sample app here, using mozTCPSocket, too:

https://github.com/soapdog/firefoxos-sample-app-telnet-client

Hi @williamkapke , Is there any way to use IPP creates a virtul Printer like pdffactory ?

@malei0083 Hm. Sorry- IPP isn't for that.

Hi @herom did you try browserify ipp? I tried it but keep getting error -0x800a138f - JavaScript runtime error: Unable to get property 'cover-back' of undefined or null reference. When try to call from browser. Must be missing something.

@williamkapke - even if you can kindly help if possible, its really big hurdle right now on project we are working.

Thank You,

Rajvi Jariwala

@rajvijariwala It's hard to say what is causing that error without seeing the code.

I have not heard of anyone successfully printing directly from the browser. Without using something like @SunboX mentioned, you are going to have Cross Domain issues.

My solution was to have a REST endpoint (in node) on a machine on the local network that browser would send data to. The endpoint would create a PDF and then use IPP to sent it to the printer. (A $30 raspberry pi?)

To the user, it seems like they are printing without the print dialog showing. It also had the added benefit of keeping the print settings away from the user so they didn't uncheck some box and mess things up! :)

HTH

Hi William,

Thank you so much for reply. For now any help and hope will make us feel so better :) Really appreciate your time. I have researched about printing from browser without print dialogue and all over internet everyone is looking this ipp node module as a real big hope. But,as you mentioned haven't seen anybody with working implementation.

We have a outfacing ASP.NET MVC application which clients(potentially high number of web based user) are going to run on their machine. What I tried was I use sample code provided in node js web application, print did work locally. Then I tried browserify the code and call it from MVC page and I could not load module successfully. I am new to node and browserify, if its doable/possible I am must be missing something (If you like I can provide code). I am really interested to make this happen and provide any efforts towards it.

I have couple questions with your suggestion:

  • Sorry I didn't get what solution you pointing to use when you say "Without using something like @SunboX mentioned..".
  • Where does this node based REST end point service needs to be installed. Can we host it on same machine with our web application and not on client machine and can still let print make happens on client side? I know I am asking too much :)
  • What is $30 raspberry pi option?

Thanks again,

Rajvi Jariwala

Hi @rajvijariwala,

As pointed out by @williamkapke, the easiest solution would be to run a printing server (e.g.: cups on Unix® system) and create an application endpoint that would handle incoming print jobs (a nodejs app for instance).

Printing workflow would be like this:

  • user click the "print" button
  • the file is sent by client with AJAX to the endpoint
  • node application behind the endpoint get a file buffer and send it to the printing server through IPP
  • printing server (e.g.: cups) send the file to printer
  • done :)

@williamkapke do you know if it exist a higher level implementation of node ipp or it is planned?
something that would allow this kind of use:

var ipp = require('some_ipp_module');
var printer = new ipp.Printer('http://some_host:631');

job = printer.printBuffer(fileBuffer);

job.on('sent', function() {
  console.log('Job ' +job.id+ ' has been sent');
});

job.on('complete', function() {
  console.log('Job ' + job.id + ' has been completed');
  // do some other stuff
});

In short, use it as a classic Javascript OOP with events support.
I recently did it using the cups lp, it works well, I even get feedback with lpq but I don't really like it and look for something more reliable. (https://github.com/alepee/node-printer)

@alepee I do not know of one that provides in interface like that. There are a few modules using it if you want to check them out though.

Hi @herom, All,

I recently Browserified the IPP module into a pure front-end browser based extension for Chrome. Allowing direct printing to IPP/CUPS from the browser. This is not very exciting unless you own a Chromebook which doesn't allow installation of printer drivers for local printing.

Link to extension is here: https://chrome.google.com/webstore/detail/ipp-cups-printing-for-chr/lkhfeoafdgbaecajkdbioenncjopbpmk?utm_source=chrome-app-launcher

Seems to work great in Chrome (not cross-browser tested as it's a Chrome extension),
Great work @williamkapke many thanks.
I haven't checked the project into GitHub, but essentially Browserifying IPP worked OOTB for me.
No special procedures required.

@DJ-hacker Awesome!! Nice work 👍

Great! Could you share your code or how you did it? I think about writing a printing app for Firefox OS. 😏

Worked for me as well. Just browserify the package and you can use it in the browser. I ran into CORS issues so I proxied the CUPS server with nginx and set CORS headers. Afterwards the virtual cups pdf printer seemed to work just fine.

I've filed a CORS feature request to the maintainers of CUPS as Issue 4850

hosting javascipt files with CUPS itself should allow access to CUPS without CORS support.
DocumentRoot is usually /usr/share/doc/cups

<script src="http://cups-host:631/ipp-stuff.js"></script>

Error
at new IppResponseError (C:\inetpub\wwwroot\printer.backend\node_modules\ipp\lib\request.js:72:17)
at ClientRequest. (C:\inetpub\wwwroot\printer.backend\node_modules\ipp\lib\request.js:40:8)
at Object.onceWrapper (node:events:436:26)
at ClientRequest.emit (node:events:329:20)
at HTTPParser.parserOnIncomingClient [as onIncoming] (node:_http_client:652:27)
at HTTPParser.parserOnHeadersComplete (node:_http_common:126:17)
at Socket.socketOnData (node:_http_client:518:22)
at Socket.emit (node:events:329:20)
at addChunk (node:internal/streams/readable:304:12)
at readableAddChunk (node:internal/streams/readable:279:9) {
statusCode: 301,
message: 'Received unexpected response status 301 from the printer'
}

Getting this error from Bizhub c227 printer.
brother or other printer are resoponse ok.

gmuth commented

Your question does not seem to relate to this issue. "printer.backend" and "node_modules" are usually not used in browser javascript. Anyway, if you get 301 as HTTP response status you probably use the wrong uri. I recommend to test your uri with curl or ipptool first - they most likely also receive the 301-moved-permanently status. For further discussion please open another issue.