• 细说Web页面与本地电脑通讯


    话说在很久很久以前。Web页面与客户的本地电脑Localhost通讯,有两种方式:

    1。Flash  2。ActiveX控件

    由于Flash本人不是很了解,也给出不了什么示例代码,

    对于ActiveX控件来说,可以直接在在网络上搜索“ActiveX控件”,就会有很多相关的答案

    但是:

      对于现代浏览器来说,以上两种方式都通通不支持了

      对于Flash来说,虽然现在浏览器还有支持,但是都不是默认加载Flash插件了

      要用户手工点同意才会加载。

      对于ActiveX控件来说,只在IE浏览器里面才受支持,而且也要用户同意,更别说现代浏览器了

    所以说。对于现代的浏览器。要与本地电脑通讯。上面两种方式已经行不通了。

    那有没有不要用户点同意,就可以直接通过Web页面与本地电脑通讯呢?

    答案是当然有了。不然也不会有此文章了。

    对于Web与服务器通讯,我们走的是HTTP协议。这也是所有浏览器都支持的
    也不会管现在浏览器和远古时代的浏览器也都支持HTTP协议。

    那么

    如果Web要与本地电脑通讯,只要Web与本地电脑走HTTP协议通讯。问题不就解决了吗?

    那怎么实现呢?

    既然要与本地电脑走HTTP协议通讯,那本地就必需要有一个支持HTTP协议的通道
    平常我们与远程服务器通讯是怎么访问的,比如说百度吧,我们输入http://www.baidu.com就能正常打开了
    那我们本地怎么办呢,我们做开发测试的时候,是不是输入:http://localhost 或者 http://127.0.0.1是不是就访问的我们本地电脑
    那么,我们在页面里向本地发送一个请求。会有什么结果?

    我们来实验一下:

    首先,既然要与本地服务器通讯。那么我们在本地要监听一下本地的http协议通讯,代码如下

    namespace LocalApp
    {
        class Program
        {
            public static HttpListener listener = new HttpListener();
            static void Main(string[] args)
            {
                listener.Start();
                listener.Prefixes.Add("http://127.0.0.1:8976/");//我们监听本地电脑8976端口的HTTP协议
                Thread t = new Thread(new ThreadStart(clientListener));
                t.Start();
                while (true)
                {
                    string s = Console.ReadLine();
                    listener.Stop();
                    listener.Close();
                }
            }
            public static void clientListener()
            {
                while (true)
                {
                    try
                    {
                        //如果收到讲求,我们就开启一个线程去处理请求
                        HttpListenerContext request = listener.GetContext();
                        ThreadPool.QueueUserWorkItem(processRequest, request);
                    }
                    catch (Exception e) { Console.WriteLine(e.Message); }
                }
            }
            public static void processRequest(object listenerContext)
            {
                try
                {
                    var context = (HttpListenerContext)listenerContext;
                    var dicPar = new Dictionary<string, string>();
                    var listPar = new List<string>();
                    //拿到请求参数
                    foreach (var item in context.Request.QueryString.AllKeys)
                    {
                        listPar.Add(String.Format("{0}={1}", item, context.Request.QueryString[item]));
                        dicPar.Add(item, context.Request.QueryString[item]);
                    }
                    //设置返回值
                    var resultJson = JsonConvert.SerializeObject(dicPar);
                    Console.WriteLine(String.Join(Environment.NewLine, listPar));
                    context.Response.StatusCode = (int)HttpStatusCode.OK;
                    context.Response.ContentLength64 = System.Text.Encoding.UTF8.GetByteCount(resultJson);
                    context.Response.ContentType = "application/json";
                    context.Response.ContentEncoding = Encoding.UTF8;
                    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                    //返回结果
                    System.IO.Stream output = context.Response.OutputStream;
                    using (StreamWriter writer = new StreamWriter(output))
                    {
                        writer.Write(resultJson);
                        writer.Close();
                    }
                }
                catch
                {
                }
            }
        }
    }

    上面的代码就是监听本地电脑8976端口的HTTP协议,
    如果收到请求。就提取参数,然后以Json的形式返回

    那么,我们写一个Html页面,向本地8976端口发送数据会出现什么情况
    代码如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="Scripts/jquery-3.3.1.js"></script>
    </head>
    <body>
        <form id="form1" enctype="application/x-www-form-urlencoded">
            <div><label>参数1:<input type="text" name="Par1" /></label></div>
            <div><label>参数2:<input type="text" name="Par2" /></label></div>
            <div><button type="button" onclick="btnSubmit()">提交</button></div>
        </form>
        <script>
            function btnSubmit() {
                $.get("http://127.0.0.1:8976/", $("#form1").serialize(), function (result) {
                    console.log(result);
                }, "json");
            }
        </script>
    </body>
    </html>

    打开Chrome浏览器做一下测试。结果如下:


    页面成功的发起了请求,本地电脑APP也监听到了Web发来了请求,参数也都拿到了。
    是不是我们就可以用这种方式用Web端来调用本地电脑的资源了

    以知问题:

    当我们的站点是以https访问的时候,如果用http去请求本地资源,而不是用https去请求的话,有些浏览器会报Mixed Content错误
    但是在新版本的谷歌与火狐已经解决了此问题,参考:https://bugzilla.mozilla.org/show_bug.cgi?id=903966


    另外一个有一个秘密,一般人我不告诉他
    你们知道当你们在本地登录了QQ后,然后打开QQ的Web站点,他为什么就能自动知道你当前登录的QQ吗?

    没错,他也用了这种方案与QQ通讯,从而知道你登录了哪个QQ,这样才会有此快速登录的功能

    思维扩展:
    这种访案只能是Web发起请求,本地电脑接受请求。只支持单一方向通讯,
    那么,有没有支持双向通讯的方案呢?(Web到本地,本地到Web)
    如果有知道答案的。可以在此博文下说出你的想法。

  • 相关阅读:
    javaji基础x3
    做一个问题,如果输入的答案正确则弹出正确,错误弹出错误
    课堂所讲整理:HTML--8Window.document对象
    课堂所讲整理:HTML--7JavaScript的DOM操作
    课堂所讲整理:HTML--6运算符、类型转换
    课堂所讲整理:HTML--5JavaScript简介
    360导航初做(修改版)
    课堂所讲整理:格式布局
    格式布局(课堂代码)
    样式表(课堂代码)
  • 原文地址:https://www.cnblogs.com/liuju150/p/Html_Web_To_Local.html
Copyright © 2020-2023  润新知