聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

五月 25, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 認識現今 Google 搜尋引擎

感謝 @Ly Cheng 針對第三點補充

new-google-logo-knockoff

1995 年 JavaScript 第1版出現,到了 1998 年 Google 推出第一代搜尋引擎,當時的 Google 根本不用在乎網頁如何使用 CSS 或 JavaScript,而當時的網頁也顯少使用 JavaScript 及 CSS。轉眼間到現在 2014 年,如今現在的 Web,已經離不開 JavaScript 及 CSS 了,而目前 SPA (Single Page Application) 的流行,也造成 Google 搜尋引擎讀取資料的困擾,所以 Google 團隊目前也正在朝這方向努力邁進。

傳統的網頁,Google 根本不需要在乎 JavaScript 或 CSS,直接從 Http Response 拿到 Body 內的資料進行分析,然而 JavaScript 的盛行,已經改變了此作法,Google 再也不能從 Body 內準確的拿到資料,原因就是現今的網頁,都已經由 JavaScript 透過 AJAX 方式跟後端存取資料,這樣對於 Google 搜尋引擎是非常不好的結果。

Google 為了改善此問題,現階段也開始著手改善爬蟲,讓爬蟲可以正確執行 JavaScript,當然也要根據 Client 端是否有打開 JavaScript。由於現在大多數的網站已經漸漸變成 SPA 方式,看到如今盛行的 JavaScript Framework 像是 Backbone.jsAngularJS 等。Google Webmaster 也開始正視這問題。

為了能讓 Google 可以正確取得網頁資料,底下有些資訊可以提供給開發者,可以對 Google 爬蟲更友善

  • 請不要將 JavaScript 或 CSS 寫入 robots.txt,這樣只是讓 Google 無法正確拿到 JavaScript 檔案
  • 注意 Server 不要拒絕 crawl requests,也就是要有能力承受 crawl 讀取 XD
  • 讓網頁可以支援舊版瀏覽器或尚未實做 JavaScript 的搜尋引擎,一樣可以正確取得網頁內容
  • JavaScript 寫的太複雜,導致 Google crawl 無法正確執行
  • 使用 JavaScript 移除 content 遠大於新增 content,避免影響 Google 做 index

現在 Google Webmaster Tools 也著手進行後台開發,讓開發者可以正確看到 Google crawl 行為。

此篇文章參考 Understanding web pages betterIt took Google’s Web crawlers 15 years to come to terms with JavaScript

十二月 7, 2013

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Javscript 18 歲生日歷史演進

resin.io 看到這篇 Happy 18th Birthday JavaScript! A look at an unlikely past and bright future. 裡面有些 Javascript 發展史,蠻有趣的,分享給大家看看。18 年前由 Netscape 和 Sun 共同 Release Javscript,在當年18天後,Ruby 也同時發佈了,底下來看看 Javscript 歷史演進。

JavaScript 發展史

1995: 由 Netscape 和 Sun 共同發佈 Javscript,並且命名為 MochaLiveScript,當時參與開發 Javascript 的其中一位負責人 Brendan Eich,現在為 Mozilla CEO。

1996: Microsoft Javscript 版本出現,並且命名為 JScript,同時發佈 Internet Explorer 3.0。這年也是 CSS 釋出第1版

1997ECMA 第1版釋出。

1998: Netscape 將 Netscape browser open source release 出來,並且成立 Mozilla Project。過了幾個月, AOL 買下 Netscape

1999: IE5 提出介紹 XMLHttpRequest

2001: IE6 正式 Release,截至目前為止,IE6 最大用戶還是在中國大陸 XD。

2002: 大家常用的 JSON 在這時候 Release,同時間 Mozilla 發佈 Firefox

2003: Apple 也不甘示弱發佈 Safari Beta Release。

2004: Google 發佈 Gmail released 產品,Gmail 用了大量 AJAX 技術,也造就現今的 Web Application。Google 挑4/1發佈,讓大家以為是惡作劇一場 XD。

2005: Apple open source Webkit,此專案是從 KHTML fork 出來的。同時間 Jesse James Garrett 發佈一篇 AJAX

2006: John Resig 發佈第1版 JQuery,現今的網站超過 90% 都會使用 jQuery,它被視為 “better cross-browser DOM API”。此年 Microsoft 同時發佈 IE 7。

2007: Douglas Crockford 講了一場 keynote 議題名稱為 JavaScript: The good parts 將來成為 O’Reilly 2008 年一本書。同年 Leonard Richardson and Sam Ruby 出了 RESTful Web Services 書。

2008: Google 推出自家瀏覽器 Chrome 和 V8 Engine,帶給瀏覽器不同的衝擊。

2009: 誰說 JavaScript 只能寫在 Client 端,Ryan Dahl 釋出 node.js,帶來用 js 寫 sever side 風潮,同年 PhoneGap 帶來 HTML5 和 JavaScript 整合到 Android 及 iOS。

2010: 一堆 JavaScript Library 同時釋出 NPM, BackboneJS, RequireJS

2012: Single-page app frameworks 出現: AngularJS 1.0, Ember 1.0.pre。

2013: Firefox OS 用 JavaScript 撰寫 UI Layer,並且正式 Release,Mozilla 同時發佈 asm.js

JavaScript 效能

Jan T. Sott 用 Kraken benchmark 發佈一篇 performance 報告,測試環境從 Firefox 3.5 to Chrome 23 同環境下測試

overall_kraken_2012

可以參考原始連結

JavaScript 生態

我們來看看眾多語言的變化

npm

可以發現 Node.js 正在往上衝阿,相信到 2015 年可以追上 Rubygems 及 Maven Central. 除了 55000+ 的 NPM package 及 6000+ package in broser 帶給使用者更好的體驗

另外 Github 也統計用其他語言寫的工具給 JavaScript 用

最後看看 Github repositories 的生態

jsgh 資料來源 Twitter,JavaScript 往上衝阿,難怪全世界都在缺 Frond End Engineer。

總結

現在用 JavaScript 寫 Client-Side 已經不稀奇了,現在有很多 Project 開始設計如何透過 JavaScript 去控制硬體,可以看到 File API and Device API 或者是 Chrome Apps, Mozilla WebAPI, and Tizen Web APIs 等專案,這些專案共通點就是希望開發者可以透過 JavaScript 來控制硬體裝置。另外也可以透過 node-webkit 來溝通。

想了解 EmbeddedJS 可以關注現有的專案或研討會 Nodebots, Nodecopter, Tessel.io, Espruino, Device.js,或者是 application 像是 heimcontrol.js and Google Coder for Raspberry Pi,很難想像 18 年後的 JavaScript 會變成什麼樣子 XD。

九月 20, 2013

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» CodeIgniter REST Server with Backbone.js Issue

CodeIgniter

如果有在用 CodeIgniter 來當作 REST Server 的朋友們,我相信都會找到 philsturgeon 所寫的 codeigniter-restserver,此套件幫你完成底層 API Response 動作,讓你可以輕易處理 REST URL。但是如果拿這套程式碼來搭配 Backbone.js 你會遇到拿不到 POST 或 PUT 變數問題,作者來一一描述。

使用 Backbone.js 來取代 jQuery AJAX 方式來跟 REST Server 溝通,當然 Backbone.js 底層還是透過 jQuery AJAX API 來傳遞,首先我們建立一個簡易的 Backbone model

// a simple backbone model
var User = Backbone.Model.extend({
    urlRoot: '/user',
    defaults:{
        'name':'appleboy',
        'age': 31
    }
});
var user1 = new User();
var user2 = new User();
var user3 = new User();

你可以建立多個使用者,或是搭配 Backbone Collection 來顯示,到這邊是沒有問題,接著要跟伺服器做 GET PUT POST DELETE 的動作,也就是透過底下 Backbone 操作

user1.fetch() // get user data
user1.save() // create or update user
user1.destroy() // delete user

這邊就會是問題所在,你會發現 backbone 丟給 REST request 的內容不會是像 jQuery AJAX 包在 parameter 內,而是在 Request Payload 內寫入 {‘name’:'appleboy’, ‘age’: 31},所以我們在 REST Server 會一直存取不到任何資料

class User extends REST_Controller
{
    public function index_get()
    {
        echo $this->get(null);
    }

    public function index_post()
    {
        echo $this->post(null);
    }

    public function index_put()
    {
        echo $this->put(null);
    }

    public function index_delete($id)
    {
        echo $this->put(null);
    }
}

問題出在 REST_Controller.php 處理 POST 函數

/**
 * Parse POST
 */

protected function _parse_post()
{
    $this->_post_args = $_POST;

    $this->request->format and $this->request->body = file_get_contents('php://input');
}

只要將上面函數改成

/**
* Parse POST
*/

protected function _parse_post()
{
    $this->_post_args = $_POST;

    $this->request->format and $this->request->body = file_get_contents('php://input');

    if (!empty($this->request->body)) {
        $this->_post_args = array_merge($_POST, json_decode($this->request->body, true));
    }
}

這樣 POST 就沒有問題了,接著如果 PUT 或 DELETE 也遇到此問題,就按照上述改相關函式。晚點發 pull request 給作者,只是不知道作者會啥時處理。

八月 15, 2013

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Cross Site Request Forgery in JS Web Apps and CodeIgniter PHP Framework

Cross Site Request Forgery 簡稱 CSRF 是網路上最常見的攻擊方式,由於前端的盛行,現在開發網站偏向前後端拆開,前端使用大量的 Javascript 及 CSS3 效果,後端則是使用 PHP, Ruby, Python… 等,前端如何拿到資料庫資料呢,必需透
過 AJAX 方式來存取,常見的後端 API 會設計成 RESTful (GET/PUT/POST/DELETE),後端為了擋住 CSRF 攻擊,所以限定了特殊 Content-Type Header,前端需要帶 application/json 給後端才可以拿到資料,這只能透過 Ajax requests 才可以做到。

但是很不幸的是使用者還是透過 header injection 方式來達到目的 (Flash exploits),所以透過判斷 Content-Type Header 這方式是不夠的。正確的防護方式就是在每個 request 給上一組 token,因為 same origin policy 關係,攻擊者無法拿到此 token,無法達到攻擊效果。

如果你是 Ruby 愛好者,可以透過 Rack CSRF 來產生 token,並且放在網頁 Head 內

在 jQuery 部份,必須使用 ajaxPrefilter 將每個 Request 加上 CSRF token 傳給伺服器

var CSRF_HEADER = 'X-CSRF-Token';
var setCSRFToken = function(securityToken) {
  jQuery.ajaxPrefilter(function(options, _, xhr) {
    if ( !xhr.crossDomain ) xhr.setRequestHeader(CSRF_HEADER, securityToken);
  });
};
setCSRFToken($('meta[name="csrf-token"]').attr('content'));

如果是在 Head 內加上 csrf-token 就必須透過上述作法,但是 CodeIgniter 並非是使用此方式,要將 CSRF 打開可以透過 config/config.php 內的

$config['csrf_protection'] = FALSE;
$config['csrf_token_name'] = 'csrf-token';
$config['csrf_cookie_name'] = 'csrf-token';
$config['csrf_expire'] = 7200;

將 csrf_protection 改成 true,這樣透過 from helper 產生的 form 表單,你會發現會多出 hidden input value,這樣送出表單的時候就可以驗證此 token 是否正確,如果你不是透過 CI form 表單產生,那也可以在 Client 端抓取 csrf-token 的 Cookie 資料,因為 CI 也會同時將 csrf-token value 寫入 Cookie,Cookie 可以透過 jQuery cookie plugin 來讀取。

另外如果你也想透過最上面 head 方式來處理,CI 那邊也可以透過 $this->security->get_csrf_hash() 來取 hash 資料,將此資料放到 html head 裡面即可。

四月 12, 2013

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» [小技巧] JavaScript Cross Browser Best Practices

ie-logo-smallie-logo-small

先前寫了一篇 modern.IE 的使用方式及介紹,今天在 Facebook 上看到 Eric Shangkuan 說已經有了中文介面,如果你的瀏覽器是中文版,應該就可以直接看到中文介面了,裡面有篇文章非常重要,寫 Web 的工程師都必須注意,那就是 Cross Browser Best Practices,這篇文章教您如何撰寫相容於舊版 IE 瀏覽器的一些小技巧,這些技巧也不只用在 IE 上,更是教您在實做 CSS,JavaScript 的注意事項。我們來看看 Javascript 的小技巧。

不要再使用 navigator.userAgent

為了知道使用者 Browser 資訊,之前有寫篇 jQuery 偵測瀏覽器版本, 作業系統(OS detection),內容使用 navigator.userAgent 來取得使用者瀏覽器及裝置資訊,開發者為了 IE 各版本的相容,所以透過此方式來知道 IE 各版本,進而在 JS 做處理,但是有時候並不是這麼準確,因為目前市面上裝置實在是太多種了,手機,平板,電視一堆等等,為了支援各種裝置,請不要再用 navigator.userAgent 來判斷了,現在取而代之的就是用 Modernizr,用來偵測您的 Browser 有無任何您所想要的功能,像是 Html5 的 Canvas,利用 Modernizr 來判斷是否支援,這時候各種裝置就不會因為 JS 沒有判斷到而產生錯誤 ,尤其是在電視介面或 Android 平板,踩到很多雷阿。詳細資訊可以參考此連結

簡單來說 Canvas 在 IE9 才有支援,所以針對 IE 部份,我們使用 navigator.userAgent 來判斷

<script type="text/javascript">
    function getInternetExplorerVersion()
    // Returns the version of Internet Explorer or a -1 for other browsers.
    {
        var rv = -1;
        if(navigator.appName == 'Microsoft Internet Explorer')
        {
            var ua = navigator.userAgent;
            varre    = newRegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
            if(re.exec(ua) != null)
            rv = parseFloat( RegExp.$1 );
        }
        return rv;
    }
    function onLoad()
    {
        var version = GetInternetExplorerVersion()
        if (version < 9 && version > -1)
        {
            // Code to run in Internet Explorer 9 or earlier.
        }
    }
</script>

但是如果遇到 Safari, Chrome, Android, IPad, IPhone 版本呢,也很好解決,就是一直些判斷式,那為什麼不換個角度去想,直接判斷有無 Cnavas 功能即可,透過 Modernizr 套件可以簡單做到。另外 jQuery 在 1.9 版也直接捨棄了 jQuery.browser API 功能,取而代之的也是推薦 Modernizr

if (Modernizr.canvas) {
  console.info('Your browser support canvas');
}

在 document ready 內不要執行大量 script

現在大部分的網站缺少不了的就是 jQuery,jQuery 提供了 $(document).ready() 在 html load 完成後可以快速執行 JavaScript,在大多的狀況下都可以正確執行的,但是如果在 $(document).ready() 寫入大量及複雜的 Script,只會讓瀏覽器呆滯而不能使用,所以盡可能減少執行的程式碼,等到使用者真正要執行功能的時候在進行呼叫即可。通常像是 tooltip 或 dialog 可以延遲等到要出現的時候在初始化即可。

簡單舉個例子,在 form 表單大家常用的 jQuery Plugin datepicker,通常初始化會透過底下方式來寫:

$(document).ready( function() {
    $("input.date").datepicker({
        minDate: moment().subtract( "months", 1 ).toDate(),
        maxDate: moment().add( "months", 1 ).toDate(),
        dateFormat: "d M, y",
        constrainInput: true,
        beforeShowDay: $.datepicker.noWeekends
    });
});

用這缺點就是當 html 完成載入後,jQuery 會開始找 input 並且符合 class 為 date 的 元件,這會 delay 使用者正常使用網頁,比較好的解決方式就是 bind 在 input 的 focus 事件上。

$(document).on( "focus", "input.date:not(.hasDatepicker)", function() {
    $(this).datepicker({
        minDate: moment().subtract( "months", 1 ).toDate(),
        maxDate: moment().add( "months", 1 ).toDate(),
        dateFormat: "d M, y",
        constrainInput: true,
        beforeShowDay: $.datepicker.noWeekends
    });
});

此寫法有另外的優點就是當如果有建立新的 input.date 元件,可以動態初始化元件。初始過的元件,我們就動態增加 hasDatepicker class 來判斷是否已經初始化。

網頁開始先優先執行 AJAX

由於執行 AJAX 需要一段時間,所以請在 html load 之前就開始執行,並不需要等到 $(document).ready() 後才執行,另外在 AJAX 完成執行後的 Complete function 加入 $(document).ready() 函式確保 html 已載入完成。

延遲載入 social button(Facebook Like, Google +1, Twitter)

現在大多網站都有一大堆分享機制(social networks),像是 Facebook Like、Twitter 等等,但是這些 JS 的載入,都大大影響到網頁的載入時間,其實最主要的解決方式就是務必思考哪些頁面才需要這些 button,能減少載入外部 JS 就是提昇網頁載入速度,在以前載入外部 JS 的作法就是底下

<script>
(function(d, s) {
  var js, fjs = d.getElementsByTagName(s)[0], load = function(url, id) {
    if (d.getElementById(id)) {return;}
    js = d.createElement(s); js.src = url; js.id = id;
    fjs.parentNode.insertBefore(js, fjs);
  };
  load('//connect.facebook.net/en_US/all.js#appId=272697932759946&xfbml=1', 'fbjssdk');
  load('http://apis.google.com/js/plusone.js', 'gplus1js');
  load('//platform.twitter.com/widgets.js', 'tweetjs');
}(document, 'script'));
</script>

現在請改寫成底下

<script>
(function(w, d, s) {
  function go(){
    var js, fjs = d.getElementsByTagName(s)[0], load = function(url, id) {
      if (d.getElementById(id)) {return;}
      js = d.createElement(s); js.src = url; js.id = id;
      fjs.parentNode.insertBefore(js, fjs);
    };
    load('//connect.facebook.net/en_US/all.js#appId=272697932759946&xfbml=1', 'fbjssdk');
    load('http://apis.google.com/js/plusone.js', 'gplus1js');
    load('//platform.twitter.com/widgets.js', 'tweetjs');
  }
  if (w.addEventListener) { w.addEventListener("load", go, false); }
  else if (w.attachEvent) { w.attachEvent("onload",go); }
}(window, document, 'script'));
</script>

由於各瀏覽器相容問題,所以判斷是否支援 addEventListener 或 attachEvent,在 onload 後才開始執行。更多詳細內容可以參考 requesting these scripts

八月 12, 2012

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 輕量級 jQuery Slideshow Plugin

相信在網路上可以找到一堆 jQuery Slideshow Plugin,例如 33 POWERFUL JQUERY SLIDESHOW (SLIDERS) PLUGINS AND TUTORIALS 介紹了 33 種不同的 Slideshow Plugin,有些用起來很複雜,有些則是過於簡易,本來是想自己寫一套出來,但是想想是否可以找一套已經有輪子的架構,再拿來修改成專案所需要的套件,於是參考了這套原始碼,發現此專案只有提供 fade 和 slide 兩種效果,沒有像是投影片可以任意滑動的功能,所以自己把此功能 patch 上去,可以參考我放到 Github 的專案,寫法很容易,可以直接看線上 Example

載入 jQuery 和 plugin

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://raw.github.com/appleboy/jquery.slideShow/master/src/jquery.slideshow.min.js"></script>

Html 和 CSS

<div class="slideShow">
    <ul class="slides">
        <li class="slide"><img src="900_360_2815b8f28c58175b52b535bf51f3e692.png" width="900" height="360" /></a></li>
        <li class="slide"><img src="900_360_46d09a37f76f27815daafc4b96e46399.png" width="900" height="360" /></a></li>
        <li class="slide"><img src="900_360_cae9a566a9a5e3a42af8b04f2ea299a0.png" width="900" height="360" /></a></li>
        <li class="slide"><img src="900_360_dd9bb48bc247ee3f8358bea788e08ce0.png" width="900" height="360" /></a></li>
        <li class="slide"><img src="900_360_63fa2bcabc296f47758d6aaebf23a530.png" width="900" height="360" /></a></li>
    </ul>
    <ul class="pager">
        <li><a href="javascript:void(0);" class="prev">Previous</a></li>
        <li><a href="javascript:void(0);" class="next">Next</a></li>
    </ul>
</div>

可以搭配後端 PHP, Python, Ruby 輸出網站輪播圖片

SlideShow Plugin

(function ($) {
    $('.slideShow').slideShow({
        interval: 3,
        start: 'random',
        transition: {
            mode: 'slideshow',
            speed: 800
        }
    });
})(jQuery);

可以自行定義輪播間隔時間,初始化為隨機或者是指定任一張圖片,以及輪播速度…等,詳細部份可以參考官方作者寫的 README

完整 Example

jQuery Slideshow Plugin Source Code

Random View

四月 9, 2012

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Javascript 前端工具 Backbone.js Framework 初學介紹

backbone

我相信大家對於後端程式 PHP, Ruby, Python .. 等語言都已經相當熟悉,進階開發者也都接觸了好用的後端 Framework 如 CodeIgniter, CakePHP, Django, Ruby on Rail, Yii, Symfony .. 等,用 Framework 最大的好處並不是在 Framework 提供了大量工具,而是制定了 MVC 架構,讓專案多位開發者可以遵循,上了講了這麼多後端 MVC Framework,那麼前端呢?接下來介紹前端強大工具: Backbone.js

什麼是 Backbone.js

簡單來說 Backbone.js 就是一套前端 Javascript Framework,它提供 MVC 架構,相信大家都玩過後端 MVC,那至於前端呢,好像比較少人提到,這就是介紹 Backbone.js 最主要的目的。Backbone.js 包含了 Model View Controller 來讓使者操作,Model 提供了key-value 結構,以及可以 binding 大量 event,開發者可以透過 RESTful JSON interface 來跟 Backbone.js 的 Model 及 Collection 搭配。如果想瞭解 Backbone.js 線上文件可以參考 GitHub 網站,如果想瞭解程式碼可以參考 source code 註解

載入 Backbone.js

在使用 Backbone.js 之前,大家必須要先瞭解,Backbone.js 有使用到兩個額外的 Library,那就是 Underscore.js( > 1.3.1) 及 jQuery( > 1.4.2),所以在 html 裡面,我們可以這樣寫

<!DOCTYPE html>
<html>
<head>
    <title>Backbone.js example</title>
    <link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
    <div class="well">
        <h1>Friend List</h1>
        <input type="text" name="username" value=""><br /><button class="btn btn-primary" id="add-friend">Add Friend</button>
        <ul id="friends-list" style="margin-top:10px"></ul>
    </div>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
</body>
</html>

使用 Backbone.js

接下來宣告 View 的作法:

window.AppView = Backbone.View.extend({
    el: $("body"),
    initialize: function () {
        this.friends = new Friends({ view: this });
    },
    events: {
        "click #add-friend":  "showPrompt"
    },
    showPrompt: function () {
        var username = $("input[name=username]").val() || "";
        alert(username);
    }
});
var appview = new AppView;

可以看到上面,程式裡面增加了一個 Clieck event,並且點選後會轉到 showPrompt 這 callback function,直接在頁面上跳出 alert 視窗,並且顯示您輸入的名稱。接下來要新增 Model 跟 Collection。

Friend = Backbone.Model.extend({
    name: null
});

Friends = Backbone.Collection.extend({
    initialize: function (options) {
        this.bind("add", options.view.addFriendList);
    }
});

宣告 Friend Model 用來設定使用者名稱,而 Friends Collection 則是用來設定多個 Model,初始化 initialize 時則設定 add event,當 Collection 有變動時,則會呼叫 View 裡面的 addFriendList function。完整 js 碼如下

(function ($) {
    Friend = Backbone.Model.extend({
        name: null
    });
   
    Friends = Backbone.Collection.extend({
        initialize: function (options) {
            this.bind("add", options.view.addFriendList);
        }
    });

    window.AppView = Backbone.View.extend({
        el: $("body"),
        initialize: function () {
            this.friends = new Friends({ view: this });
        },
        events: {
            "click #add-friend":  "showPrompt",
            "click .delete":  "delete_li"
        },
        delete_li: function(e) {
            $(e.currentTarget).parent().remove();
        },
        showPrompt: function () {
            var username = $("input[name=username]").val() || "";
            this.friend_model = new Friend({'name': username});
            this.friends.add(this.friend_model);
        },
        addFriendList: function (model) {
            $("#friends-list").append("<li style='margin-top:5px;'>Friend name: " + model.get('name') + " <button class='btn btn-danger delete'>Delete Friend</button></li>");
        }
    });
    var appview = new AppView;
})(jQuery);

當使用者按下新增按鈕時,程式將 username 設定到 model 裡,並且將此 model 丟入 Collection。而 Collection 有變動時,會呼叫 addFriendList 函式,將結果輸出到 #friends-list tag。完整程式碼可以參考: Source Code

線上範例(Example)

Related View

四月 17, 2011

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 你不可不知的 JSON 基本介紹

還不知道 JSON 是什麼嘛?本篇教學會帶您瞭解 JSON 在網站上的應用,以及運作流程跟使用 PHPJavaScript 來處理 JSON。假如您現在的工作就是網站設計師,相信一定聽過 JSON,但是什麼是 JSON,它能夠做什麼,及您能透過它在網站上做到哪些事情呢?

透過本篇介紹您可以瞭解基本的 JSON,底下會列出本篇會提到的重點:

  • 什麼是 JSON
  • JSON 應用在哪些地方
  • 如何建立 JSON 字串
  • 一個簡單的 JSON 範例
  • JSON vs XML
  • 如何透過 PHP 及 JavaScript 使用 JSON

什麼是 JSON

JSON 是個以純文字為基底去儲存和傳送簡單結構資料,你可以透過特定的格式去儲存任何資料(字串,數字,陣列,物件),也可以透過物件或陣列來傳送較複雜的資料。一旦建立了您的 JSON 資料,就可以非常簡單的跟其他程式溝通或交換資料,因為 JSON 就只是純文字個格式。

JSON 的優點如下:

  • 相容性高
  • 格式容易瞭解,閱讀及修改方便
  • 支援許多資料格式 (number,string,booleans,nulls,array,associative array)
  • 許多程式都支援函式庫讀取或修改 JSON 資料

JSON 應用在哪些地方

JSON 最常用用在 Web 網頁程式從 Server 端傳送資料給 browser,典型範例就是透過 AJAX 方式交換 JSON 資料,底下簡單舉個範例

1. 使用者點選了線上產品縮圖
2. JavaScript 透過 AJAX 方式將產品 ID 傳送給伺服器端
3. 伺服器端收到 ID,將產品資料 (ex 價格,描述) 編碼成 JSON 資料,並且回傳給瀏覽器
4. JavaScript 收到 JSON 資料,將其解碼 (decode) 並且將資料顯示在網頁上

您也可以透過網頁將 JSON 資料傳到伺服器端,這都是可以的,把 POST 或 GET 資訊編碼成 JSON 格式即可,如果有在使用 jQuery,它提供了兩個函式處理 JSON,分別是 getJSONparseJSON

如何建立 JSON 字串

可以透過底下規則來建立 JSON 字串

1. JSON 字串可以包含陣列 Array 資料或者是物件 Object 資料
2. 陣列可以用 [ ] 來寫入資料
3. 物件可以用 { } 來寫入資料
4. name / value 是成對的,中間透過 (:) 來區隔

物件或陣列的 value 值可以如下:

1. 數字 (整數或浮點數)
2. 字串 (請用 “” 括號)
3. 布林函數 (boolean) (true 或 false)
4. 陣列 (請用 [ ] )
5. 物件 (請用 { } )
6. NULL

一個簡單的 JSON 範例

{
  "orderID": 12345,
  "shopperName": "John Smith",
  "shopperEmail": "johnsmith@example.com",
  "contents": [
    {
      "productID": 34,
      "productName": "SuperWidget",
      "quantity": 1
    },
    {
      "productID": 56,
      "productName": "WonderWidget",
      "quantity": 3
    }
  ],
  "orderCompleted": true
}

由上面例子我們可以發現 contents 陣列裡面又包含物件,透過上面例子,我們寫成 JavaScript 如下:

<script type="text/javascript">
var cart = {
  "orderID": 12345,
  "shopperName": "John Smith",
  "shopperEmail": "johnsmith@example.com",
  "contents": [
    {
      "productID": 34,
      "productName": "SuperWidget",
      "quantity": 1
    },
    {
      "productID": 56,
      "productName": "WonderWidget",
      "quantity": 3
    }
  ],
  "orderCompleted": true
};
</script>

JSON vs XML

在許多方面,你可以想像 JSON 來替代 XML,在過去 Web Application 開發 AJAX 都是透過 XML 來交換資料,但是你可以發現近幾年來 JSON 已經漸漸取代 XML 格式了,為什麼會變成這樣呢?因為 JSON 格式容易閱讀且好修改,許多程式語言分別開發了函式庫來處理 JSON 資料,我們可以把上面的 JSON 資料改寫成 XML 如下:

<object>
  <property>
    <key>orderID</key>
    <number>12345</number>
  </property>
  <property>
    <key>shopperName</key>
    <string>John Smith</string>
  </property>
  <property>
    <key>shopperEmail</key>
    <string>johnsmith@example.com</string>
  </property>
  <property>
    <key>contents</key>
    <array>
      <object>
        <property>
          <key>productID</key>
          <number>34</number>
        </property>
        <property>
          <key>productName</key>
          <string>SuperWidget</string>
        </property>
        <property>
          <key>quantity</key>
          <number>1</number>
        </property>        
      </object>
      <object>
        <property>
          <key>productID</key>
          <number>56</number>
        </property>
        <property>
          <key>productName</key>
          <string>WonderWidget</string>
        </property>
        <property>
          <key>quantity</key>
          <number>3</number>
        </property>
      </object>
    </array>
  </property>
  <property>
    <key>orderCompleted</key>
    <boolean>true</boolean>
  </property>  
</object>

大家有沒有發現 XML 的資料量遠大於 JSON 資料量,這也是 JSON 優於 XML 的原因之一

如何利用 JavaScript 來處理 JSON 資料

直接看例子比較快:

<script type="text/javascript">

var cart = {
  "orderID": 12345,
  "shopperName": "John Smith",
  "shopperEmail": "johnsmith@example.com",
  "contents": [
    {
      "productID": 34,
      "productName": "SuperWidget",
      "quantity": 1
    },
    {
      "productID": 56,
      "productName": "WonderWidget",
      "quantity": 3
    }
  ],
  "orderCompleted": true
};

alert ( JSON.stringify( cart ) );

</script>

透過 JSON.stringify 來轉換資料,產生結果如下

{"orderID":12345,"shopperName":"John Smith","shopperEmail":"johnsmith@example.com",
"contents":[{"productID":34,"productName":"SuperWidget","quantity":1},
{"productID":56,"productName":"WonderWidget","quantity":3}],
"orderCompleted":true}

如何將 JSON 字串傳入 JavaScript 變數

<script type="text/javascript">

var jsonString = '                          \
{                                           \
  "orderID": 12345,                         \
  "shopperName": "John Smith",              \
  "shopperEmail": "johnsmith@example.com",  \
  "contents": [                             \
    {                                       \
      "productID": 34,                      \
      "productName": "SuperWidget",         \
      "quantity": 1                         \
    },                                      \
    {                                       \
      "productID": 56,                      \
      "productName": "WonderWidget",        \
      "quantity": 3                         \
    }                                       \
  ],                                        \
  "orderCompleted": true                    \
}                                           \
'
;

var cart = JSON.parse ( jsonString );

alert ( cart.shopperEmail );
alert ( cart.contents[1].productName );

</script>

結果如下
cart.shopperEmail 輸出 johnsmith@example.com
cart.contents[1].productName 輸出 WonderWidget

利用 PHP 建立或讀取 JSON 資料

PHP 直接有寫好函式庫可以處理 JSON 字串,就是利用 json_encodejson_decode

範例:

<?php
$cart = array(
  "orderID" => 12345,
  "shopperName" => "John Smith",
  "shopperEmail" => "johnsmith@example.com",
  "contents" => array(
    array(
      "productID" => 34,
      "productName" => "SuperWidget",
      "quantity" => 1
    ),
    array(
      "productID" => 56,
      "productName" => "WonderWidget",
      "quantity" => 3
    )
  ),
  "orderCompleted" => true
);

echo json_encode( $cart );
?>

輸出

{"orderID":12345,"shopperName":"John Smith","shopperEmail":"johnsmith@example.com","contents":[{"productID":34,"productName":"SuperWidget","quantity":1},{"productID":56,"productName":"WonderWidget","quantity":3}],"orderCompleted":true}

大家可以發現,我們只要用 array 方式將資料輸出,再透過 json_encode 就可以了,接下來看看底下 PHP 如何讀取 JSON 字串

<?php
$jsonString = '
{                                          
  "orderID": 12345,                        
  "shopperName": "John Smith",              
  "shopperEmail": "johnsmith@example.com",  
  "contents": [                            
    {                                      
      "productID": 34,                      
      "productName": "SuperWidget",        
      "quantity": 1                        
    },                                      
    {                                      
      "productID": 56,                      
      "productName": "WonderWidget",        
      "quantity": 3                        
    }                                      
  ],                                        
  "orderCompleted": true                    
}                                          
'
;

$cart = json_decode( $jsonString );
echo $cart->shopperEmail . "<br>";
echo $cart->contents[1]->productName . "<br>";
?>

很簡單吧,PHP 利用了 json_decode 方式將 json 轉成變數資料以便讀取內容。

結論

這篇介紹主要是讓大家對 JSON 有基本得瞭解,以及如何用 JavaScript 跟 PHP 處理 JSON 資料,其實就不難,希望對大家有幫助。

本篇範例皆來自 JSON Basics: What You Need to Know 文章

Related View

三月 31, 2011

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 2011 OSDC Day 1 筆記

今年很高興可以北上參加 OSDC 2011 (Open Source Developers Conference),由於之前都在南部唸書及工作,沒有機會北上參加聚會,現在人在新竹,終於有機會可以參加了,雖然早上六點就要起床趕電車了,不過到現場聽課感覺就是不同,也可以認識很多新朋友,底下來紀錄上課筆記

1.微軟與 jQuery 社群的親密接觸

講者: Eric Shangkuan (Microsoft)
Slide: 微軟與 jQuery 社群的親密接觸

這是 OSDC 第一場演講,早上九點就開始了,雖然人不多,但是蠻多人還是為了講者而來,首先介紹什麼是 jQuery,以及 jQuery 一些基本用法,像是 CSS selector,如何在 Windows Visual Studio 上面開發 jQuery 及撰寫 plugin 整合進去 ASP.Net,最後介紹三個不錯用的 jQuery Plugin: Templeate, Datalink, Globalzation

  • Templeate: 這搭配 Facebook api 可以直接做個人頁面,請參考這裡
  • Globalzation: 前端多國語系實做
  • Datalink: 可以快速處理 form,利用 object 跟 jQuery 搭配

如果要研究上述三個 jQuery Plugin 可以參考底下:
jQuery Datalink: https://github.com/jquery/jquery-datalink
jQuery Templeate: https://github.com/jquery/jquery-tmpl
jQuery Globalzation: https://github.com/jquery/jquery-global

2. HandlerSocket – A NoSQL plugin for MySQL

講者: Jui-Nan Lin (PIXNET)
Slide: HandlerSocket – A NoSQL plugin for MySQL

會後有部份聽眾提出了一些問題,PIXNET 也已經回報給 MySQL 請他們修復這些問題,可以參考 gslin 大神回覆的這篇: MySQL HandlerSocket 的情況…,不過 NoSQL 有個缺點就是沒有帳號密碼,這部份蠻好解覺的,因為 DB 都直接放在後面,前面加上防火牆就好了。

3. Use command line tool in Python

講者:hychen
Slide: Use command line tool in Python

此主題前面先介紹 Python command line 一些基本技巧,最後講到 ucltip 這支 hychen 撰寫的 Python tool。

import commands
ret=commands.getoutput('ls -al')

subprocess - Replacing os.system (不支援 shell 變數)

subprocess.call(['ls', '-al'])
subprocess.call(['ls', '-al', '$HOME'])

所以利用 shlex 將變數轉換 (處理 argument, parameter)

4. 從 U-boot 移植 NDS32 談嵌入式系統開放原始碼開發的一些經驗

講者:macpaul
Slide: 從 U-boot 移植 NDS32 談嵌入式系統開放原始碼開發的一些經驗

這場是我覺得第一天講得最好的,可能現在大部分科技業都在實做嵌入式系統,所以聽起來特別有感覺,裡面包含一些 Linux Kernel C 語言開發程式的 Codeing Style,這塊我認為相當重要阿,每次看到同事的程式碼,幾乎沒有排版過,看到眼睛相當不舒服,講者介紹了 u-boot 的歷史,還有本篇最重要的就是如何提交 (submit) patch,講者被國外打很多槍的經驗分享,雖然自己本身是 FreeBSD committer,知道這些格式都很重要,FreeBSD 有自訂指令 follow 的格式,那 Kernel Driver 部份也是有 standard。講者介紹兩套 diff patch tool: filterdiff, splitdiff。Coding Style 請參考底下:

當然版本控制主推 Git 了,現在幾乎所有 Kernel 版本都是用 git 下去維護。

5. Trading with opensource tools, two years later

講者:Chia-liang Kao
Slide: Trading with opensource tools, two years later

此講者利用 Perl 開發了一套分析一些股市債倦的系統,幫助自己下單,其實還蠻屌的,分享了開發上實做的一些經驗,以及主機的規劃,由於作者喜歡泡溫泉,所以取名 Trade Spring,大家有興趣可以看看投影片

6. Yappo Groonga – with japanese search software history

講者:yappo
Slide: Yappo Groonga – with japanese search software history

講者介紹一套在日本文字上面開發的 Search engine,官方網站:groonga.org,在現場其實它很想用英文表達很多意思,可是好像也表達不出來,有些階段是用日文,但是有時候用英文,看了文件都只有支援日文,講者也提到現在已經快把英文文件寫好了,我自己本身是用 Sphinx,在本網站搜尋可以找到 Sphinx 相關文件

第一天早上超早去,結果不小心在微軟攤位抽到一本 jQuery 實戰手冊,早起的鳥兒有蟲吃,我看阿民也有抽到 XD。

Related View

十月 6, 2010

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» jQuery 偵測瀏覽器版本, 作業系統(OS detection)

update: 簡易版的偵測 iphone/ipod time: 23:32 jQuery 真是一個相當方便的 javascript framework,最近在弄嵌入式系統時候需要去偵測瀏覽器 user agent,就類似下此訊息 “Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)“,原本打算直接用 C 語言內建的 getenv(”HTTP_USER_AGENT”) 來做掉,不過後來想想,直接在 UI 那邊,利用 jQuery 來偵測瀏覽器版本、系統OS,這樣就解決了,上網找到有人寫了 jQuery browser and OS detection plugin,利用底下語法就可以知道一些 user agent 裡面的資料 ...詳全文(共1112字)

八月 26, 2010

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» [CodeIgniter] 利用 jQuery 簡易驗證使用者帳號/Email

好久沒寫相關 CodeIgniter 文章,針對於剛入門 CI 的新手們,此篇教學如何使用 jQuery AJAX 搭配 CI 來驗證使用者帳號及相關資訊,本篇教學帶您如何在 CI 中發出 AJAX request 給伺服器端。 ...詳全文(共1532字)

七月 30, 2010

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» [網站] 好站連結 (七) Android, javascript, Css, PHP, Perl, FreeBSD, Linux

Windows C# C# 比較字串 MSDN 比較字串 Request.Form Collection Request Query String / Form Parametrs ...詳全文(共1347字)

五月 28, 2009

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» [網站] 好站連結 (二)


PHP

MySQL

WWW

jQuery

html

FreeBSD

javascript

MySQL

Linux

Related View

五月 6, 2009

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud