jquery uploader

使用ajax upload還滿常使用到,但是又不需要一些複雜的功能,所以就寫了一個簡單的jquery uploader

需求如下:
  1. 將form經用ajax post出去。
  2. 選擇要post的欄位包括file。
支援:
  1. firefox
  2. chrome
  3. IE10+

使用ajax submit整個form:

//opts.success(result):上傳成功
//opts.progress:處理進度
//opts.fail:上傳失敗

$("form").uploadForm( opts );

uploadForm會自動抓取form的action連結,目前此plugin只能一次抓取一個form upload。

使用ajax submit部份欄位:

//url:要上傳的目標連結

$( "input[name='file'],input[name='id']" ).upload( url, opts );

如果要支援IE10以下瀏覽器,現在已經另外實作iframe uploader,目前可以支援uploadForm這個功能,但是僅支援success這個參數。

github

X-Frame-Options response header

如果要防止頁面被iframe或frame嵌入,比較常用的方法是,在頁面上加入一串script做判斷,或者加入X-Frame-Options header。

X-Frame-Options有下列3個參數值可用:
deny

拒絕被任何嵌入頁面。

SAMEORIGIN

允許來至於相同domain的嵌入。

ALLOW-FROM uri

允許某個domain嵌入。

 

以下是用node.js寫得example:
var express = require('express');

var html = "from http://localhost:3001/SAMEORIGIN<br>" +
            '<iframe src="http://localhost:3001/SAMEORIGIN"></iframe><br>'+
            'from http://localhost:3001/deny<br>' +
            '<iframe src="http://localhost:3001/deny"></iframe><br>' +
            'from http://localhost:3001/allow_from<br>' +
            '<iframe src="http://localhost:3001/allow_from"></iframe><br>';

(function(){       

  var app = express();

  app.get('/', function(req, res){

    res.send( html );
  });

  app.listen(3000);

})();

(function(){

  var app = express();

  app.get('/', function(req, res){

    res.send( html );
  });

  app.get('/SAMEORIGIN', function(req, res){
    res.set('X-Frame-Options','SAMEORIGIN');
    res.send('hello world');
  });

  app.get('/deny', function(req, res){
    res.set('X-Frame-Options','deny');
    res.send('hello world');
  });

  app.get('/allow_from', function(req, res){
    res.set('X-Frame-Options','Allow\-From http://localhost:3001');
    res.send('hello world');
  });

  app.listen(3001);

})();

需先安裝node.jsexpress.js

#使用npm安裝express
npm install express

#執行server.js
node server.js

分別測試http://localhost:3000/ and http://localhost:3001/,其中allow-from測試時,似乎沒辦法取得正確結果,換成其他domain頁面一樣是可讀取的。

Zend framework page cache

初始projectt為例,可直接至application.ini配置cache的參數。

;關閉預設buffer
resources.frontController.params.disableOutputBuffering = true

resources.cachemanager.page.frontend.name = Page
;cache存活時間      
resources.cachemanager.page.frontend.options.lifetime = 5
;debug模式,會在header最上方顯示提示
resources.cachemanager.page.frontend.options.debug_header = true
;儲存的容器
resources.cachemanager.page.backend.name = File
;設定存放位置
resources.cachemanager.page.backend.options.cache_dir = APPLICATION_PATH "/cache"

;如果不一定要在自身project底下建立cache的目錄
;可直接導向到/tmp即可,以下的權限修改跟folder建立都可以省略
;/tmp底下檔案,當電腦關閉時,將會自動清除
;resources.cachemanager.page.backend.options.cache_dir = "/tmp"

建立cache folder和修改權限:

cd newproject/application

mkdir cache

sudo chown www-data:www-data cache

在controller init的加入要cache的action:

// 註冊 Cache Action Helper
$this->_helper->addHelper(new Zend_Controller_Action_Helper_Cache());

$this->_helper->cache(array(
  'index', // 指定要快取的 Action
));

以IndexController為例如下:

class IndexController extends Zend_Controller_Action      
{

    public function init()      
    {     
        /* Initialize action controller here */   

        // 註冊 Cache Action Helper                 
        $this->_helper->addHelper(new Zend_Controller_Action_Helper_Cache());

        $this->_helper->cache(array(
            'index', // 指定要快取的 Action
        ));

    }

    public function indexAction()
    {              
        // action body
    }
}

當使用debug mode的時候,就會在頁面上出現"DEBUG HEADER : This is a cached page !"的字樣,表示目前是使用cache。

Installation zend framework

官方下載(以1.12.3 version為例),然後解壓縮:

wget https://packages.zendframework.com/releases/ZendFramework-1.12.3/ZendFramework-1.12.3.zip

unzip ZendFramework-1.12.3.zip

建置project和copy library:

./ZendFramework-1.12.3/bin/zf.sh project newproject

cp -r ./ZendFramework-1.12.3/library ./newproject/library

會產生以下檔案及目錄:

.
|-- application
|   |-- Bootstrap.php
|   |-- configs
|   |-- controllers
|   |-- models
|   `-- views
|-- docs
|   `-- README.txt
|-- library
|   `-- Zend
|-- public
|   `-- index.php
`-- tests
    |-- application
    |-- bootstrap.php
    |-- library
    `-- phpunit.xml

最後在配置server(apache、nginx…)即可,以下是用nginx設定:

server {

    listen 80;
    server_name localhost;

    #path:/etc/nginx/sites-enabled/default

    root /var/www/newproject;
    index  index.html index.htm index.php;

    location / {
        if (!-f $request_filename) {
            rewrite "^(.*)$" /public/index.php?q=$1 last;
            break;
        }
    }

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/newproject$fastcgi_script_name;
        include fastcgi_params;
    }   
}

從上方配置可看到,使用$request_filename,判斷該檔案路徑存不存在,將所有不存在的url導向index.php,在由index.php去分派給controller,如果存在則直接導向該檔案。

最後打開http://localhost就可以看到配置好的project首頁了。

Zend framework core cache

zend framework提供了Zend_Cache::factory,這個factory可以產生出好幾種cache方式,官方範例如下:

// We choose a backend (for example 'File' or 'Sqlite'...)
$backendName = '[...]';

// We choose a frontend (for example 'Core', 'Output', 'Page'...)
$frontendName = '[...]';

// We set an array of options for the chosen frontend
$frontendOptions = array([...]);

// We set an array of options for the chosen backend
$backendOptions = array([...]);

// We create an instance of Zend_Cache
// (of course, the two last arguments are optional)
$cache = Zend_Cache::factory($frontendName,
                             $backendName,
                             $frontendOptions,
                             $backendOptions);

frontendName:

指的是快取對象,例如資料、頁面、檔案。

backendName:

指的是要儲存的容器,例如存入檔案裡、sqlite、或者是連接至Memcache server等…。

frontendOptions和backendOptions:

指的是可選參數值。

可參考官方frontend cachebackend cache

在前台頁面中,有一些資料可能是很久才去更新一次,這時就可以使用cache:
  • 如果是採用page cache,那可能要只cache一部分頁面,透過ajax抓取,或者直接在view上面加判斷式。
  • 透過file cache可直接將抓取到的api資料,直接存入,只要每次去檢查cache時效是否過了,如果時效過則在重新抓取。
以下是一個簡單example:
class FileCache {

    private $cache;

    public function FileCache( $lifetime = 300 ){
        // 設定 Frontend 選項
        $frontendOptions = array(
           'lifetime' => $lifetime, // 快取時間
           'automatic_serialization' => true, // 自動 serialization
        );  
        // 設定 Backend 選項
        $backendOptions = array(
            'cache_dir' => APPLICATION_PATH . '/cache/', // 快取存放路徑
        );  
        // 建立一個快取物件
        $this->cache = Zend_Cache::factory('Core',
                                           'File',
                                           $frontendOptions,
                                           $backendOptions);

    }   

    public function load( $name ){
        return $this->cache->load( $name );
    }   

    public function save( $name, $data ){
        return $this->cache->save( $data, $name );
    }

    public function isAvailable( $name ){
        return $this->cache->test( $name );  
    }   
}

使用方式如下:

$cache = new FileCache( 60 );

$cacheName = "data_cache";

if( $cache->isAvailabel( $cacheName ) ){

    $result = $cache->load( $cacheName );
}else{

    $result = array(1,2,3,4,5);
    $cache->save( $cacheName, $result )
}

print_r( $result );

Titanium command line

titanium的環境都安裝好之後,就可以找到~/.titanium這路徑,然後在.bashrc加上以下配置。

1
alias titanium.py=$HOME/.titanium/mobilesdk/linux/3.0.0.GA/titanium.py

接著執行:

1
source .bashrc

然後建立一個project:

1
titanium.py create --platform=android --android=/path/to/android-sdk --id=com.mycompany.myApp --name=myApp

會建立出以下檔案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.
|-- build
| `-- android
| |-- AndroidManifest.xml
| |-- assets
| |-- bin
| |-- default.properties
| |-- gen
| |-- lib
| |-- res
| `-- src
|-- LICENSE
|-- manifest
|-- README
|-- Resources
| |-- android
| | |-- appicon.png
| | |-- default.png
| | `-- images
| |-- app.js
| |-- KS_nav_ui.png
| `-- KS_nav_views.png
`-- tiapp.xml

啟動android的模擬器:

1
titanium.py emulator --platform=android --android=/path/to/android-sdk

如果需要使用到google api,可等待建立後,至avd調整。

最後在把project run在模擬器上:

1
titanium.py run --platform=android --android=/path/to/android-sdk

可參考官方文件