顯示具有 Javascript 標籤的文章。 顯示所有文章
顯示具有 Javascript 標籤的文章。 顯示所有文章

2016年8月10日 星期三

HTML5 Server-Sent Event

什麼是Server-Sent Event?

因為有個功能更強大的Websocket Api的存在, 很多人應該都沒聽過Server-Sent Event. 其實它跟 Long polling 是很類似的. 主要的差別在於 Server-Sent Event 的事件是由browser處理的, client 端只需要listen for messages.

Server-Sent Event 比較 Websocket

Websocket雖然功能強大, 但有些情況, 用Server-Sent Event會比較符合效益.例如:
  1. 像是資訊交換是非雙向, 單純只是client端在接收資料, 而client不需要回傳資料. 
  2. 資源不足. 例如: Server 是虛擬主機, 沒有root的權限或是不能執行特定程式來架起Websocket server.

Server-Sent Event 屬性/方法


屬性/方法 說明
urlEventSource 中指定的 URL
readystateEventSource 的狀態
CONNECTING0 : 代表試著與SERVER連線
OPEN1 : 連線成功
CLOSE2 : 關閉連線
onopen連線成功時會呼叫的事件
onmessage接收到資料的時候會呼叫的事件
error發生錯誤時會呼叫的事件, 發生錯誤後不會重試連線
close()中斷與SERVER的連線, 中斷後不會再重試連線


Server-Sent Even 範例

client.html
 <!DOCTYPE html>  
 <html lang="zh-TW">  
      <head>  
           <meta charset="utf-8">  
           <meta http-equiv="X-UA-Compatible" content="IE=edge">  
           <meta name="viewport" content="width=device-width, initial-scale=1">  
           <!--[if lt IE 9]>  
                <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>  
                <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>  
           <![endif]-->  
      </head>  
      <body>  
      <div class="body">  
           <div class="container">  
                <header>  
                     <button onclick="stop();">stop</button>  
                </header>  
                <main>  
                     <div id="result"></div>  
                     <div id="ce"></div>  
                </main>  
           </div>  
      </div>  
           <script>  
                var source = new EventSource("serverside.php");  
                source.onmessage = function(event) {  
                     console.log('new message, msg type', typeof(event.data));  
                     document.getElementById("result").innerHTML = event.data + "<br>";  
                };  
                function stop(){  
                     source.close();  
                }  
           </script>  
      </body>  
 </html>  


serverside.php

 <?php  
 header('Content-Type: text/event-stream');  
 header('Cache-Control: no-cache');  
 $time = date('r');  
 echo "data: The server time is: {$time}\n\n";  
 ?>  

格式說明:

  1. serverside 一定要把header定義為 Content-Type: text/event-stream
  2. 要推送的資料前面一定要加 data:
  3. 結尾一定要多斷一行

自定義事件

Server-Sent Event可以同時推送不同的資料. 假設, 同一個頁面要更新的資料有好友線上狀態跟新通知, 我們可以在serverside 定義出兩個事件

 <?php  
 header('Content-Type: text/event-stream');  
 header('Cache-Control: no-cache');  
 echo "event: myEvent_1\n";  
 echo "data: my Custom event msg {$time}\n";  
 echo 'data:' . json_encode(array("username"=> "John123", "status"=> "online")) . "\n\n";  
 echo "event: myEvent_2\n";  
 echo "data: my Custom event msg {$time}\n";  
 echo 'data:' . json_encode(array("title"=> "notification", "msg"=> "You've got mail")) . "\n\n";  
 ?>  

然後在client.html用addlistener來監聽這兩個事件

 <script>  
 source.addEventListener('myEvent_1', function(event){  
                     var obj = JSON.parse(event.data.split('\n')[1]);  
                     document.getElementById("ev1").innerHTML += obj.username+" : "+obj.status+"<br>";  
                }, false)  
                source.addEventListener('myEvent_2', function(event){  
                     var obj = JSON.parse(event.data.split('\n')[1]);  
                     document.getElementById("ev2").innerHTML += obj.title +" : "+obj.msg+"<br>";  
                }, false)  
 </script>  

範例可以在 這裡 下載

2016年5月31日 星期二

如何解決 Jquery.map() 回傳 'prevObject' 的問題

今天在處理一個table的時候出現一個問題,
我用jquery.map()去loop through 所有已勾選的checkbox並吧該勾選的資料放入一個array做為回傳的資料.

結果在看console時發現array 變成

[x,x,x,x,x, prevObject: jQuery.fn.jQuery.init[7], context: ]

根據我在這裡找到的答案是:

當你用jquery.map()的時候, 它回傳的是一個jquery collection而不只是迴圈內你所形成的array. 所以你需要在後面加一個toArray()來存取你要的array.

例.

$(selector).map(function(i,v){
//Do something....
}).toArray();
就可以只取陣列, 而不取多餘的資料了

2016年3月25日 星期五

Node JS + Express JS + Passport JS 做一個登入系統 & 多個帳號綁定的範例

教學出處

安裝所需要的模組


  1. Express
  2. mongoose
  3. passport
  4. passport-facebook
  5. connect-flash
  6. bycrypt-nodejs
  7. morgan
  8. body-parser
  9. cookie-parser
  10. express-session
以上都用npm安裝, 沒接觸過的請自行GOOGLE

建立檔案的結構

- app
------ routes.js     //處理路由
-models               //所有DB的操作都放在這裡
------ user.js
- config               //設定檔都放這
------ auth.js      //處理串接社群API的設定(ClientId, Secret, callbackUrl...etc)
------ database.js //設定DB連線的參數
------ passport.js //設定passport的認證策略
- views
------ index.ejs    //起始畫面, 選擇登入的方式
------ login.ejs     //登入畫面
------ signup.ejs   //註冊畫面
------ profile.ejs   //登入後顯示個人檔案
- server.js             //沒什麼好解釋的, 就是SERVER

Server.js


DB設定 config/database.js



路由 app/routes.js

我們用以下的路由來試範
  • 首頁 : /
  • 登入頁 : /login
  • 註冊頁 : /signup
  • 處理登入 (POST)
  • 處理註冊 (POST)
  • 個人檔案: /profile

User model 



Passport.js