Xiaopei's DokuWiki

These are the good times in your life,
so put on a smile and it'll be alright

User Tools

Site Tools


it:express

express

Tips

  • expressjs/multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. It is written on top of busboy for maximum efficiency.
    • NOTE: Multer will not process any form which is not multipart (multipart/form-data).
  • express session 至少到 1.10 都只支持 cookie session id,不支持 url 或 http header 做 session id
  • 关于 middleware
    • If the current middleware does not end the request-response cycle, it must call next() to pass control to the next middleware, otherwise the request will be left hanging.
    • An error-handling middleware has an arity of 4, which must always be maintained to be identified as an error-handling middleware. Even if you don’t need to use the next object, make sure specify it to maintain the signature, else it will be interpreted as a regular middleware, and fail to handle errors.
  • 不使用 view 但有提示的 302 跳转
    res.status(302)
    .header("Content-Type", "text/html; charset=utf-8")
    .header('refresh','5; url=xiaopei.li')
    .end('马上跳转!');
  • full url
    var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;

kraken

  • krakenjs/kraken-js/ An express-based Node.js web application bootstrapping module.
  • Dust
    • 中文文档
    • 核心(Dust.js | Getting Started 文档看这篇就够了):
    • helpers
      • {@eq} 等对比 helper 在做数字类型的对比时,应该加 type=“number”
      • makara 还缺很多功能
        # properties 中:
        # 不能定义层级对象
        features[1].title = foo, bar
        features[1].content = foo, bar. foo, bar. foo, bar. 
        
        # dust 中:
        # 不能按 key 调用数组/对象
        {@pre type="content" key="features[1]"/}
        # 或
        <span class="some-list">
        <a href="#" title="l10n hint [0]">l10n label [0]</a>
        <a href="#" title="l10n hint [1]">l10 lable [1]</a>
        ...
        </span>
    • 主要的第三方 helpers:rragan/dust-motes Repository for contributed helper and filter extensions to dust
    • dustmotes-provide Provide rich dust parameter definitions.
      # @provide 结合 @pre 使用,遍历 properties 中定义的数组/对象
      {@provide selected=chosen}
        <select name="states">
          {#stateList}
            <option value="{$id}"
                    {@if cond="'{selected}' == '{$id}'"} selected="selected" {/if}>
              {$elt}
            </option>
          {/stateList}
        </select>
      {:stateList}
        {@pre type="content" key="stateList" mode="paired" /}
      {/provide}
  • krakenjs/adaro A Dust.js view renderer for express
  • krakenjs/generator-kraken Yeoman generator for kraken.js apps
    $ yo kraken:controller myController
    Generates a new controller namespace called myController and it's dependencies.
    
    $ yo kraken:model myModel
    Generates a new model named myModel.
    
    $ yo kraken:template myTemplate
    Generates a new template named myTemplate and it's dependencies.
    
    $ yo kraken:locale myFile [myCountry myLang] Generates a new content bundle named myFile.

kraken 的组件

使用 redis 储存 session

krakenjs 的 readme 中有说明:krakenjs/kraken-js#extending-default-middleware

lusca

  • 默认全开,但对部分路由关闭 CSRF 防护 RESTfull API in kraken (and CSRF) #193 - krakenjs/kraken-js
    {
        "middleware": {
     
            /**
             * Overrie default lusca configuration to disable CSRF handling. (See below.)
             */
            "appsec": {
                "module": {
                    "arguments": [
                        {
                            "xframe": "SAMEORIGIN",
                            "p3p": false,
                            "csp": false
                        }
                    ]
                }
            },
     
            /**
             * Enable *ONLY* CSRF filtered by route.
             */
            "csrf": {
                "enabled": true,
                "priority": 111,
                "route": "/((?!api))*",
                "module": {
                    "name": "lusca",
                    "method": "csrf",
                    "arguments": [ {} ]
                }
            }
     
        }
     
    }

passport

在 kraken 中使用用户名、密码登陆的步骤(参考:Authenticating Node.js Applications With Passport - Tuts+ Code Tutorialkrakenjs/kraken-examples/tree/master/with.passport):

  1. @todo

如果需要在 LocalStrategy 中使用 req,则需要如下修改:

passport.use(new LocalStrategy({ passReqToCallback: true }
  function(req, username, password, done) {
    // ...
  }
));

Allow extra parameters to local verify call #3

init / yo / gitignore

express

# 安装 express 命令
$ npm install -g express
# 使用 ejs 模板建立 photo 项目
$ express -e photo
$ cd photo && npm install
# 此时, package.json 的 "dependencies" 中是 "ejs": "*" 的, 为了确保版本, 需要...
$ npm install ejs --save 
# 启动
$ node app
# 使用不同环境启动 (默认是 develop)
$ NODE_ENV=production node app

yo & grunt

    • Make sure you have yo installed: npm install -g yo
    • Install the generator locally: npm install generator-express
    • Run: yo express
    • Run: grunt to run the local server at localhost:3000, the grunt tasks include live reloading for .jade views, css in public/stylesheets and restarting the server for changes to app.js or js in routes/

gitignore

  • gitignore
    lib-cov
    *.seed
    *.log
    *.csv
    *.dat
    *.out
    *.pid
    *.gz
    
    pids
    logs
    results
    
    npm-debug.log
    node_modules

connect

Connect - High quality middleware for node.js

var app = connect()
  .use(connect.logger('dev'))
  .use(connect.static('public'))
  .use(function(req, res){
    res.end('hello world\n');
  })
 .listen(3000);

express 是基于 connect 的.

dust

我写的一些 dust helper

'use strict';
 
var _ = require('lodash'),
    numeral = require('numeral'); // https://github.com/foretagsplatsen/Numeral-js
 
 
    /**
     *
     * 结构:
     *
     * <span class="moneyClass">prefix format(val)</span> suffix
     *
     * 一般 prefix 为 symbol,suffix 为 unit
     *
     * Example:
     *
     * 1. 默认效果
     *
     * {@money val=siteData.result.total_investor_fee /}
     *
     * 可得到:
     *
     * <span class="">¥384,833,535.99</span> 元
     *
     *
     * 2.
     *
     * {@money val=siteData.result.total_investor_fee divide="10000"
     *         moneyClass="ui-fs-large ui-fw-bold ui-fc-orange"
     *         prefix="" suffix="万元" /}
     *
     * 可得到:
     *
     * <span class="ui-fs-large ui-fw-bold ui-fc-orange">
     *   38,483.35
     * </span> 万元
     *
     */
    dust.helpers.money = function(chunk, context, bodies, params) {
 
        var val = dust.helpers.tap(params.val, chunk, context),
            format = dust.helpers.tap(params.format, chunk, context),
            moneyClass = dust.helpers.tap(params.moneyClass, chunk, context),
            prefix = dust.helpers.tap(params.prefix, chunk, context),
            // prefix 会包在 money span 中
            suffix = dust.helpers.tap(params.suffix, chunk, context),
            divide = dust.helpers.tap(params.divide, chunk, context),
            // “除数”是 divisor,而不是 divide + r,为避免写错,所以
            // 没用 divisor 直接用 divide
            ret = '';
 
        // 除
        if (!_.isUndefined(divide)) {
            val = val / divide;
        }
 
        // 设置(默认)格式
        if (_.isUndefined(prefix)) {
            prefix = '¥';
        }
        if (_.isUndefined(suffix)) {
            suffix = '元';
        }
        if (_.isUndefined(format)) {
            format = '0,0.00';
        }
        if (_.isUndefined(moneyClass)) {
            moneyClass = '';
        }
 
        // numeral().format() 不支持在 format 中直接加 ¥ 等符号,
        // 所以 prefix、suffix 在 format() 后加;
        // 数字、文字之间要加空格;
        ret = '<span class="' + moneyClass + '">' +
            prefix + numeral(val).format(format, Math.floor) +
            '</span>' + (suffix ? ' ' + suffix : '');
 
        return chunk.write(ret);
    };
 
    /**
     *
     * 用来判断是否打印 active 类的 helper
     *
     */
    dust.helpers.active = function(chunk, context, bodies, params) {
 
        var val = dust.helpers.tap(params.val, chunk, context),
            match = dust.helpers.tap(params.match, chunk, context),
            activeClass = dust.helpers.tap(params.activeClass, chunk, context),
            ret = '';
 
        if (val === match) {
 
            if (_.isUndefined(activeClass)) {
                ret = 'active';
            }
            else {
                ret = activeClass;
            }
        }
 
        return chunk.write(ret);
    };
it/express.txt · Last modified: 2015/12/22 15:14 by admin