細說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)
如果有知道答案的。可以在此博文下說出你的想法。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章