之前给公司做打印都是用ActiveX控件,只支持IE浏览器,最近需要支持谷歌,又不想去学谷歌插件编写,于是就用本地启动一个http服务器来供浏览器调用(写成windows服务更好),同事用了都说好(笑)!为了方便大家使用,重新简单的封装了一下,源码下载:点我下载

源码简单的封装了一个webserver(基于httplistener,可以使用Nancy框架代替),可以大致了解HTTP服务器处理的流程:APACHE,NINGX等服务器主要负责响应浏览器HTTP(基于SOCKET)的请求,并将请求转交给JAVA,C#,PHP等语言处理(应该就是启动了一个该语言的虚拟机解析执行对应的代码),再将处理结果返回给浏览器

 1 namespace LocalPrint.Web
 2 {
 3     //本地微型HTTP服务器,可以理解网络请求处理的服务器处理流程
 4     class WebServer
 5     {
 6         HttpListener httpListener;
 7         public string Err;
 8         Dictionary<string, IHttpHandler> handlerMap = new Dictionary<string, IHttpHandler>();
 9         //启动本地HTTP服务器,相当于APACHE,NGINX之类的WEB服务器,接受浏览器发送过来的SOCKET请求
10         public bool RunWeb(string url)
11         {
12             try
13             {
14                 httpListener = new HttpListener();
15                 httpListener.Prefixes.Add(url);
16                 httpListener.Start();
17                 var th = new Thread(Process);
18                 th.IsBackground = true;
19                 th.Start();
20                 return true;
21             }
22             catch (Exception ex)
23             {
24                 Err = "启动本地服务器出现问题:" + ex.Message;
25                 return false;
26             }
27         }
28         //设置相应路由和相应的处理类
29         public bool AddHandler(string url,IHttpHandler httpHandler)
30         {
31             try
32             {
33                 handlerMap.Add(url, httpHandler);
34                 return true;
35             }
36             catch (Exception ex)
37             {
38                 Err = "添加路径出错:" + ex.Message;
39                 return false;
40             }
41         }
42         //HTTP数据处理,这一部分相当于C#,JAVA和PHP和其他语言的功能,WEB服务器将请求转发给相应的语言处理,并把结果返回给浏览器
43         void Process()
44         {
45             for (; ; )
46             {
47                 var cnx = httpListener.GetContext();//获取浏览器请求上下文,串行处理,也可以改成并行
48                 var req = cnx.Request;
49                 var rep = cnx.Response;
50                 rep.ContentEncoding = Encoding.UTF8;
51                 rep.Headers.Add("Access-Control-Allow-Origin", "*");//允许浏览器跨域!非常重要
52                 rep.StatusCode = 404;
53                 var ret = "pag not found";
54                 //rep.ContentType = "text";//返回内容,这里为text,ajax里面的请求datatype也需要设置为text或者html,不然会为null
55                 //这一部分其实就是大部分MVC网络框架里的路由部分!这里简单的发送原始文本给handler处理
56                 foreach (var kv in handlerMap)
57                 {
58                     if(System.Text.RegularExpressions.Regex.IsMatch(req.RawUrl,kv.Key))//正则匹配
59                     {
60                         var data = "";
61                         if (req.HttpMethod == "GET")
62                             data = req.RawUrl;//不做任何处理,直接将原始的http请求转发到handler。。。
63                         else
64                         using (var r = new StreamReader(req.InputStream, Encoding.UTF8))
65                         {
66                             data = r.ReadToEnd();
67                         }
68                         ret = kv.Value.Handler(data);
69                         rep.StatusCode = 200;//ok
70                         break;
71                     }
72                 }
73                 //返回处理结果给浏览器
74                 using (var w = new StreamWriter(rep.OutputStream, Encoding.UTF8))
75                 {
76                     w.WriteLine(ret);
77                 }
78             }
79         }
80
81     }
82 }

 1         void Process()
 2         {
 3             for(; ; )
 4             {
 5                 var cnx = httpListener.GetContext();
 6                 var req = cnx.Request;
 7                 var rep = cnx.Response;
 8                 rep.Headers.Add("Access-Control-Allow-Origin", "*");
 9                 var txt = "";
10                 if (req.HttpMethod == "POST")
11                 {
12                     var fp = "";
13                     using (var r = new StreamReader(req.InputStream, Encoding.UTF8))
14                     {
15                         fp = r.ReadToEnd();
16                     }
17                     var printer = req.QueryString["printer"];
18                     switch (req.Url.LocalPath)
19                     {
20                         case "/printZPP":
21                             printComp1.Print(fp, printer);
22                             break;
23                         case "/printTJBB":
24                             printComp1.PrintBB(fp, printer);
25                             break;
26                         case "/printQD":
27                             printComp1.PrintQd(fp, printer);
28                             break;
29                         case "/printAll":
30                             printComp1.UniversalPrint(fp, printer);
31                             break;
32                         default:
33                             //rep.StatusCode = 404;
34                             txt = "404";
35                             break;
36                     }
37                 }
38                 else
39                 {
40                     switch (req.Url.LocalPath)
41                     {
42                         case "/GetPrintNames":
43                             txt = printComp1.GetPrinterNames();
44                             break;
45                         case "/GetPrinter":
46                             {
47                                 var id = req.QueryString["id"];
48                                 txt = printComp1.GetLocalPrinter(id);
49                             }
50                             break;
51                         case "/SetPrinter":
52                             {
53                                 var id = req.QueryString["id"];
54                                 var printer = req.QueryString["printer"];
55                                 printComp1.SetLocalPrinter(id, printer);
56                             }
57                             break;
58                                 default:
59                                 txt = printComp1.GetPrinterNames();
60                                 //rep.StatusCode = 404;
61                                 txt = "404";
62                             break;
63                     }
64                 }
65
66                 using (var w = new StreamWriter(rep.OutputStream, Encoding.UTF8))
67                 {
68                     w.WriteLine(txt);
69                 }
70             }
71         }

HTTP处理接口,PrintHandler派生此接口处理打印任务,也可以派生接口执行其他本地任务,只是简单的处理get和post文本,没有具体的参数解析,需要类自行解析。。。

1     //类似于MVC框架的ACTION或者CONTROLER,可派生此接口实现其他操作
2     public interface IHttpHandler
3     {
4         string Handler(string txt);//简单的处理文本消息
5     }

IPrint打印接口,派生此接口执行具体打印任务,打印格式这块可以封装出一整套的处理代码(常用的标签,表格打印和格式设置),有空再处理了
1     //打印接口,需要打印格式,派生此接口即可
2     public interface IPrint
3     {
4         bool Print(Graphics g);//返回值为是否还有打印需要打印的页内容,即是否打印结束
5     }

启动本地服务器后,浏览器直接访问或ajax跨域访问本地服务器即可调用本地处理服务!

 1 $.ajax({
 2           url : "http://localhost:23333/print",
 3           type : "POST",
 4           contentType: "application/json;charset=utf-8",
 5           data : "{'name':'大萝卜卜','age':32,'sex':true}",
 6           dataType : "text",
 7           success : function(result) {
 8             if (result == "ok") {
 9               alert("打印成功!");
10             } else {
11               alert("打印出错:"+result )
12             }
13           },
14           error:function(msg){
15            aler('Error:'+msg);
16           }
17         })

本地测试

            var web = new WebClient();var txt = textBox1.Text;byte[] bytearray = Encoding.UTF8.GetBytes(txt);txt = Convert.ToBase64String(bytearray);txt = System.Web.HttpUtility.UrlEncode(txt, Encoding.UTF8);//必须经过url编码web.Encoding = Encoding.UTF8;web.Headers.Add("ContentType", "application/x-www-form-urlencoded");try{var ret = web.UploadString("http://127.0.0.1:1234", "POST", "args=" + txt);textBox2.Text = Encoding.UTF8.GetString(Convert.FromBase64String(ret));}catch (WebException ex){var rsp = ex.Response as HttpWebResponse;if(rsp !=null){var code = (int)rsp.StatusCode;textBox2.Text = code + "\r\n";var stream = rsp.GetResponseStream();using (var s = new StreamReader(stream)){textBox2.Text += s.ReadToEnd();}}else{textBox2.Text = ex.Message;}}

为了发表博客,花了2个小时,把代码整理,简单的封装成接口,平常写代码哪有这么费事,分分钟写完交差了事(意大利面条,笑),写文章不易,点个赞吧。

转载于:https://www.cnblogs.com/HelliX/p/9318008.html

基于HTTP可供浏览器调用的本地打印程序相关推荐

  1. chrome浏览器插件启动本地应用程序

    chrome浏览器插件启动本地应用程序 2014-04-20 00:04:30|  分类: 浏览器插件|举报|字号 订阅 下载LOFTER 我的照片书  | chrome的插件开发这里就不多讲了,本篇 ...

  2. UC 浏览器调用支付宝本地支付

    近期观察到:在 UC 浏览器中打开网页进行支付宝支付时,会自动调起支付宝 APP 进行支付. 针对这个现象今天分析了一下 UC 浏览器的实现方案. 发现在UC 上进行支付(也就是访问支付宝 WEB A ...

  3. 从浏览器调用qt开发客户端程序

    目录 方法一: Windows实现: 1.web端 2.客户端写入注册表 3.测试验证 MacOS实现:

  4. linux backtrack函数,Linux调用backtrack函数打印程序崩溃时的调用堆栈

    可以给自己的程序都加上这个东西,便于快速的找到错误吧,看到别人都是这么用的 #include #include #include #include //signal 函数用法参考http://www. ...

  5. js打开android应用程序,浏览器通过JS打开Android程序

    做项目的时候,项目中有个需求,需要通过网页打开app,听到这个功能,我先是蛋疼了一会,但是在网上查了一下资料发现原理其实很简单,本质就是通过浏览器输入我们本地android程序的路径,不过这个路径需要 ...

  6. js 打开android浏览器,浏览器通过JS打开Android程序

    做项目的时候,项目中有个需求,需要通过网页打开app,听到这个功能,我先是蛋疼了一会,但是在网上查了一下资料发现原理其实很简单,本质就是通过浏览器输入我们本地android程序的路径,不过这个路径需要 ...

  7. Crawler:反爬虫之基于urllib库+伪装浏览器方式实现从各种网站上(以百度贴吧为例)获得你喜欢的照片下载到本地电脑上

    Crawler:反爬虫之基于urllib库+伪装浏览器方式实现从各种网站上(以百度贴吧为例)获得你喜欢的照片下载到本地电脑上 目录 输出结果 实现代码 输出结果 后期更新-- 实现代码 import ...

  8. 浏览器调用本地应用程序

    第一次遇到这个问题是比较蒙的,后来查找资料后逐渐有了思路: IE 浏览器可以使用 ActiveX控件,但会有风险(我并未去验证). 使用URL ,通过将URL协议添加到注册表的方法(我打算采用这种方法 ...

  9. 基于浏览器调用ARKit与ARCore

    浏览器调用ARKit 这两天苹果出了新品发布会的预告,官网的页面还有个小彩蛋就是用浏览器调用ARCore实现的,着色器的效果看着舒服.附上链接https://www.apple.com.cn/appl ...

最新文章

  1. @async 默认线程池_.NET Web应用中为什么要使用async/await异步编程?
  2. 20060911: 新机器·流氓软件
  3. Linux网络状态工具ss命令操作详解
  4. Silverlight 同域WCF免跨域文件
  5. Leetcode 23.移除元素
  6. 作者:刘勇,山东农业大学教授、博士生导师。
  7. 损失函数——交叉熵损失函数
  8. C# ASP.NET 权限设计 完全支持多数据库多语言包的通用权限管理系统组件源码
  9. java.lang.ClassNotFoundException: com.sun.xml.ws.spi.ProviderImpl解决办法
  10. 集群间动态扩展和删除hdfs的datanode和hbase的regionserver
  11. php算法求出一个数可以被分解成多少个_程序员的算法趣题
  12. edius隐藏快捷键_Eduis快捷键,大家参考一下!【EDIUS】史上最全的EDIUS快捷键资料分享!...
  13. 怎样在html中加入动态图片背景,怎样在网页中插入透明flash背景 添加透明flash背景方法介绍(图文)...
  14. AOP(面向切面编程)
  15. 计算机程序是指为解决某一问题,在计算机中为解决某一特定问题二设计的指令程序是...
  16. 微信公众平台版面设计需要服务器,公众号版面设计,微信公众号中排版怎么弄...
  17. 中年人的崩溃从浏览器崩溃开始
  18. 为ibus输入法框架制作新世纪五笔码表
  19. linux服务器---代理认证
  20. 【spring的使用方法】

热门文章

  1. 娱乐弹弹弹——程序猿眼中的女人
  2. 关于RPN中proposal的坐标回归参数的一点理解及Faster R-CNN的学习资料
  3. 全套BAT大厂面试题整理锦集
  4. excel合并多个工作簿
  5. iar定义arm版本_Keil MDK 和 IAR 两款ARM开发工具区别比较
  6. 内部存储器——①静态存储器
  7. nagios的安装及nrpe的配置
  8. 对计算机财务管理的理解,计算机财务管理.doc
  9. C1——primitives添加gltf并实现旋转、缩放、平移
  10. 图解PKCS#1(合)