How to send/request IPP (Internet Printing Protocol) messages from Javascript
Product JSPrintManager Published 03/14/2024 Updated 03/14/2024 Author Neodynamic
Overview
JSPrintManager supports IPP (Internet Printing Protocol) Communication from Javascript allowing you to Send/Request IPP JSON messages to any IPP URI device and get IPP JSON response from the client system. Based on pure Javascript code, you can enable IPP Comm on any web page (written on top of any Web Platform including ASP.NET MVC/CORE, PHP, Django, Ruby On Rails (RoR), Express.js, Angular, React, Vue).
In this walkthrough, you'll learn how to Send/Request IPP JSON messages to any IPP URI device and get IPP JSON response from Javascript. This solution works with any popular browser like Chrome, Firefox, IE/Edge & Safari on Windows, Linux, Raspberry Pi, Android and Mac systems!
The sample code in this article will perform the following IPP tasks on the specified IPP Device URI:
- Get Printer Attributes: Will return an IPP JSON object containing all the printer attributes like name, supported papers, and many more!
- Get Completed Jobs: Will return an IPP JSON object containing all the completed jobs including the job ID, job Name, job State, etc.
- Print a Plain Text file: Will print a plain text content and will return an IPP JSON object containing the job ID and related into.
- Print a PDF file: Will print a PDF file content and will return an IPP JSON object containing the job ID and related into. IMPORTANT! The target printer must support printing PDF docs natively otherwise an error response will be issued back by the printer.
Follow up these steps
-
JSPrintManager Client App
Be sure you install in your dev machine JSPrintManager (JSPM) (Available for Windows, Linux, Raspberry Pi, Android & Mac)
IMPORTANT: This small app must be installed on each client! -
HTML & Script References
- Download JSPrintManager.js
- Copy all of these *.js files to the same folder where the next
index.html
page sample will be located in. - By using your favorite Web Development IDE or Text Editor, create a new HTML file naming it
index.html
Copy/paste the following code inside that html file:
<!DOCTYPE html> <html> <head> <title>JSPrintManager</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> <meta charset="utf-8" /> <style> table, textarea { width: 100%; height: 200px; padding: 3px; } a { cursor: pointer; } </style> </head> <body> <div style="text-align:center"> <h1>IPP (Internet Printing Protocol) Comm from Javascript</h1> <hr /> <label> IPP Device URI <input id="txtDeviceUri" value="ipp://10.0.0.1:631" /> </label> <hr /> <button onclick="ippGetPrinterAttributes();">Get Printer Attributes...</button> <button onclick="ippGetCompletedJobs();">Get Completed Jobs...</button> <button onclick="ippPrintTextFile();">Print Text Plain File...</button> <button onclick="ippPrintPdfFile();">Print PDF File...</button> <hr /> <div> <textarea id="txtDataReceived" readOnly style="background-color:#302a2a;color:#fff;font-family: 'Courier New', Courier, monospace;" cols="100" rows="10"></textarea> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.5/bluebird.min.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> <script src="scripts/JSPrintManager.js"></script> <script> //WebSocket settings JSPM.JSPrintManager.auto_reconnect = true; JSPM.JSPrintManager.start(); //Check JSPM WebSocket status function jspmWSStatus() { if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Open) return true; else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Closed) { alert('JSPrintManager (JSPM) is not installed or not running! Download JSPM Client App from https://neodynamic.com/downloads/jspm'); return false; } else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Blocked) { alert('JSPM has blocked this website!'); return false; } } //IPP tasks... function ippGetPrinterAttributes() { if (jspmWSStatus()) { $('#txtDataReceived').val(""); let printerUri = $("#txtDeviceUri").val(); // Get Printer Attributes let ippMsgGetPrinterAttributes = { version: { major: 1, minor: 1 }, operationId: JSPM.Ipp.GET_PRINTER_ATTRIBUTES, requestId: 1, groups: [ { tag: JSPM.Ipp.OPERATION_ATTRIBUTES_TAG, attributes: [ { tag: JSPM.Ipp.CHARSET, name: 'attributes-charset', value: ['utf-8'] }, { tag: JSPM.Ipp.NATURAL_LANG, name: 'attributes-natural-language', value: ['en-us'] }, { tag: JSPM.Ipp.URI, name: 'printer-uri', value: [printerUri] }, { tag: JSPM.Ipp.KEYWORD, name: 'requested-attributes', value: ['all'] } ] } ] } JSPM.JSPrintManager.sendIppMessage(printerUri, ippMsgGetPrinterAttributes).then((data) => { $('#txtDataReceived').val(JSON.stringify(data)); console.info(data); }).catch((m) => { $('#txtDataReceived').val('ERROR: ' + m); console.error(m); }) } } function ippGetCompletedJobs() { if (jspmWSStatus()) { $('#txtDataReceived').val(""); let printerUri = $("#txtDeviceUri").val(); // Get Completed Jobs let ippMsgGetCompletedJobs = { version: { major: 1, minor: 1 }, operationId: JSPM.Ipp.GET_JOBS, requestId: 1, groups: [ { tag: JSPM.Ipp.OPERATION_ATTRIBUTES_TAG, attributes: [ { tag: JSPM.Ipp.CHARSET, name: 'attributes-charset', value: ['utf-8'] }, { tag: JSPM.Ipp.NATURAL_LANG, name: 'attributes-natural-language', value: ['en-us'] }, { tag: JSPM.Ipp.URI, name: 'printer-uri', value: [printerUri] }, { tag: JSPM.Ipp.KEYWORD, name: 'which-jobs', value: ['completed'] }, { tag: JSPM.Ipp.KEYWORD, name: 'requested-attributes', value: ['job-id', 'job-state', 'job-state-reasons', 'job-name', 'job-media-sheets-completed'] } ] } ] } JSPM.JSPrintManager.sendIppMessage(printerUri, ippMsgGetCompletedJobs).then((data) => { $('#txtDataReceived').val(JSON.stringify(data)); console.info(data); }).catch((m) => { $('#txtDataReceived').val('ERROR: ' + m); console.error(m); }) } } function ippPrintTextFile() { if (jspmWSStatus()) { $('#txtDataReceived').val(""); let printerUri = $("#txtDeviceUri").val(); // Print a Plain Text file let ippMsgPrintFile = { version: { major: 1, minor: 1 }, operationId: JSPM.Ipp.PRINT_JOB, requestId: 1, groups: [ { tag: JSPM.Ipp.OPERATION_ATTRIBUTES_TAG, attributes: [ { tag: JSPM.Ipp.CHARSET, name: 'attributes-charset', value: ['utf-8'] }, { tag: JSPM.Ipp.NATURAL_LANG, name: 'attributes-natural-language', value: ['en-us'] }, { tag: JSPM.Ipp.URI, name: 'printer-uri', value: [printerUri] }, { tag: JSPM.Ipp.NAME_WITHOUT_LANG, name: 'job-name', value: ['HelloWorldTest'] }, { tag: JSPM.Ipp.MIME_MEDIA_TYPE, name: 'document-format', value: ['application/octet-stream'] } ] }, { tag: JSPM.Ipp.JOB_ATTRIBUTES_TAG, attributes: [ { tag: JSPM.Ipp.INTEGER, name: 'copies', value: [1] }, { tag: JSPM.Ipp.KEYWORD, name: 'media', value: ['iso_a4_210x297mm'] } ] } ] } let enc = new TextEncoder(); let txtFileBinContent = enc.encode("Hello World - Printed by JSPrintManager through IPP!"); JSPM.JSPrintManager.sendIppMessage(printerUri, ippMsgPrintFile, txtFileBinContent).then((data) => { $('#txtDataReceived').val(JSON.stringify(data)); console.info(data); }).catch((m) => { $('#txtDataReceived').val('ERROR: ' + m); console.error(m); }) } } function ippPrintPdfFile() { if (jspmWSStatus()) { $('#txtDataReceived').val(""); let printerUri = $("#txtDeviceUri").val(); // Print a PDF file let ippMsgPrintFile = { version: { major: 1, minor: 1 }, operationId: JSPM.Ipp.PRINT_JOB, requestId: 1, groups: [ { tag: JSPM.Ipp.OPERATION_ATTRIBUTES_TAG, attributes: [ { tag: JSPM.Ipp.CHARSET, name: 'attributes-charset', value: ['utf-8'] }, { tag: JSPM.Ipp.NATURAL_LANG, name: 'attributes-natural-language', value: ['en-us'] }, { tag: JSPM.Ipp.URI, name: 'printer-uri', value: [printerUri] }, { tag: JSPM.Ipp.NAME_WITHOUT_LANG, name: 'job-name', value: ['PrintPdfTest'] }, { tag: JSPM.Ipp.MIME_MEDIA_TYPE, name: 'document-format', value: ['application/pdf'] } ] }, { tag: JSPM.Ipp.JOB_ATTRIBUTES_TAG, attributes: [ { tag: JSPM.Ipp.INTEGER, name: 'copies', value: [1] }, { tag: JSPM.Ipp.KEYWORD, name: 'media', value: ['iso_a4_210x297mm'] } ] } ] } // Get PDF binary file content var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://neodynamic.com/temp/LoremIpsum.pdf', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) { if (this.status == 200) { let pdfFileBinContent = new Uint8Array(xhr.response); JSPM.JSPrintManager.sendIppMessage(printerUri, ippMsgPrintFile, pdfFileBinContent).then((data) => { let errorCode = ''; if (data._oprationIdOrStatusCode && data._oprationIdOrStatusCode > 0) { errorCode = 'ERROR!!! ' + JSPM.Ipp[data._oprationIdOrStatusCode] + '\n\n'; } $('#txtDataReceived').val(errorCode + JSON.stringify(data)); console.info(data); }).catch((m) => { $('#txtDataReceived').val('ERROR: ' + m); console.error(m); }) } } xhr.send(); } } </script> </body> </html>
- That's it! Run your website and test it.