2014年4月9日 星期三

Javascript Note(2)

這禮拜的web作業是使用asp來對一些request在server端做處理,必須承認,asp和php實在太像啦!可以直接將code內嵌在html中!概念上就跟php一樣使用tag來區別asp還是html

話說我個人對microsoft就是有偏見,加上又是使用Mac的關係!沒辦法安裝asp(就算可以也不想XD),所以只好使用Nodejs來寫這次的作業,不過老實說Nodejs真的還不錯,只要懂一點Javascript後,上手真的還蠻容易的,而且使用Nodejs來建立web server有個好處就是我不用去安裝像Asp或是LAMP之類的環境,只需要單存的把寫好的web server給run起來就完成喏,想法上就跟Python的Django一樣,不過Django缺點是包了不少內容在裡面(畢竟是framework),上手比較沒那麼容易,Nodejs的framework相對簡單不少XD!!由於這次作業曾經瘋狂的google一些Javascript的技巧,包括Nodejs,容器的一些應用,覺得之後應該會蠻有用的,記錄在此啦~~~

  • Nodejs create web server
  • parse client ip address & referer
  • Javascript using stack and queue
  • Javascript container(some dictionary tips)

Nodejs create web server

老實說之前再碰LAMP的時候,一直很好奇為什麼我可以在*.php的當按裡面寫html,好吧!當時實在太廢,這種簡單的問題困擾惹不少時間!簡單來說LAMP是由Linux+Apache+mysql+php,所組成的一個web server環境,為什麼說是"環境"而不是就簡單說web server呢?web server其實只是一個服務程式而已,而這隻程式run再遠端的電腦,負責針對client端的request做response,這是web server主要的工作,但是如果client有表單資訊的話,要怎麼存取?如果webserver直接將檔案寫成一個file存起來,那很容易,可是非常的雜亂無章,而且安全性堪慮,所以啦!這種時候就會把工作丟給資料庫程式來處理!那麼PHP這個直譯器語言要負責做啥呢?簡單來說就是負責CGI的部分,與client端坐一些互動,這就是LAMP!!而PHP的處理方式是當request到server要一份*.php的檔案,webserver會先去判段這份*.php中哪些是php的code segmentation,然後丟給php直譯器產生結果然後連同html tag丟給client端,其實丟過去的封包可以簡單想成就是一堆string,只是這些string在到達client後會以server端的該檔案做命名並暫存在瀏覽器的cache中!

LAMP的web server為鼎鼎大名的Apache,他在Linux的背景做執行,所以啦!當你預設開機就會開啟web server服務的話,Apache就在背景無聲無息啟動!以前還傻傻思考很久為什麼只要把html或php丟到www的資料夾client就可以得到網頁!其實道理很簡單,在背景執行的Apache會直接去搜尋該資料夾下的html或php,然後傳給client端!

不過LAMP還蠻肥的,而且有個大缺點在Apache中,那就是蠻吃資源的,當連線數量過高時,在電腦爛爛的情況下,很容易當機,不過在這裡不會特別探討LAMP和Nodejs的優缺點,google的資料一大堆!就不描述喏!接下來就是要直接用Server端的Javascript,來創建一個簡單,輕量化的web server

var server,
    url,
    port,
    fs;

url = require('url');
http= require('http');
fs  = require('fs');
port = 5566;

// create http server by using http module
server = http.createServer(function(req,res){

   // parse client request
   path = url.parse(req.url);
   switch(path.pathname){
      case '/':
         //open main.html
         fs.readFile(__dirname+'/'+'main.html','utf8',function(err,file){
            
            if(err){

               res.writeHead(404,{'Content-type':'text/plain',});
               res.end();
               return;
            }
            // set response head      
            res.writeHead(200,{'Content-type':'text/html'});
            // end represent all data finish
            // if want send data but not finish: using res.write(data)
            res.end(file);
         });
         break;
      // open slave.html
      case '/slave.html':

        fs.readFile(__dirname+path.pathname,'utf8',function(err,file){
            if(err){

               res.writeHead(404,{'Content-type':'text/plain'});
               res.end();
               return;
            }

            res.writeHead(200,{'Content-type':'text/html'});
            res.end(file);
         });
         break;

      default: 
         res.writeHead(404,{'Content-type':'text/plain'});
         res.end();
         break;
   }

}).listen(port);


parse client ip address & referer

大陸經常用proxy server來翻牆,因為有proxy server的關係,那麼我們要怎麼讓server知道client的ip address?很簡單,將client的ip address寫到http request的header就行啦!這個header的name就是x-forwarded-for,所以要怎麼parse client的ip呢?只要下方的幾行Javascript就可以辦到

var ip = req.headers['x-forwarded-for'] || 
     req.connection.remoteAddress || 
     req.socket.remoteAddress ||
     req.connection.socket.remoteAddress;

那要怎麼知道前一頁是誰呢?只要去parse header的referer就行惹

var path = req.headers.referer

Javascript using stack and queue

身為程式設計師,stack和queue這兩種資料結構常常避免不了要使用他們,在Javascript中很貼心的已經把這兩樣東西納入Array的物件當中,可以參考下圖(來源:JavaScript 的列隊 (Queue) 和堆疊 (Stack))


Javascript container(some dictionary tips)

不得不說,dictionary這個容器使用頻率非常的高,在Javascript使用dictionary可以如下宣告

var dict = {};

其實就是宣告物件啦!然後可以直接把key和value直接填入

dict["one"] = "First";
dict["two"] = "Second";
dict["three"] = "Third";

當然,有時候避免不了要對diction sort,例如我們宣告了下面的key和value

var dict = {};
dict["five"] = 5;
dict["four"] = 4;
dict["three"] = 3;
dict["two"] = 2;
dict["one"] = 1; 

這時如果要對value sort要怎麼辦呢?很可惜的是object並沒有提供sort的方法,不過很幸運的是Array有提供,所以這時要將我們的dictionary改成用Array,咦?用dictionary改用Array?想法上就是直接把key和value用object包起來然後用push丟到Array裡面去

var arr = new Array();
arr.push({key: 'five', val: 5});
arr.push({key: 'four', val: 4});
arr.push({key: 'three', val: 3});
arr.push({key: 'two', val: 2});
arr.push({key: 'one', val: 1});

然後用Array的sort method就可以啦!

arr.sort(function(a,b) {
    return a.val - b.val;
});

需要注意的是,我們常常判斷key是不是在dictionary裡面,如果是dict用object create的話可以直接使用"in" operator

var dict = {};
dict["ker"] = 1;
dict["lala"] = 2;
if("ker" in dict){
    // do something
}

但如果用Array來模擬dictionary的話則無法直接用"in" operator,這時可以宣告一個function來判斷


dict = [];
arr.push({key: 'five', val: 5});
arr.push({key: 'four', val: 4});
arr.push({key: 'three', val: 3});
arr.push({key: 'two', val: 2});
arr.push({key: 'one', val: 1});

function isKeyInDict(str){

   for(i=0;i<dict.length;i++){
      if(dict[i].key == str){
         return i;
      }
   }
   return -1;
}

var index = isKeyInDict(str);
if(index < 0){
    // do something
}else{
    // do other thing
}

沒有留言:

張貼留言