node.js与express4.X实战--快速构建一个简单的API接口(翻译)

来源:互联网 发布:Mac 不能共享文件夹 编辑:程序博客网 时间:2024/05/18 21:46

对于express 新手来说,我推荐一个 express脚手架工具。

npm install -g express-generator

这里写图片描述

通过上面命令安装express脚手架工具,接下来

exress -e myapp

生成一个express的框架(参数e代表使用ejs模板,默认是jade模板)
这里写图片描述

今天主要用做一个接口,如果是同源策源允许下的情况json就返回json,请求是JSONP就返回JSONP。

1.首先在routes目录下新建一个api.js,拷贝同目录下index.js下的内容到api.js,这个文件后面将做处理json还是jsonp接口的内容。

2.打开app.js, 在

var users = require(‘./routes/users’);

后面添加

var api = require(‘./routes/api’);

app.use(‘/users’, users);

后面添加

app.use(‘/api’, api);

上面操作就是加载依赖模块api路由处理文件,然后对某个路径处理。

题外话:这是express官方的写法,采用其经典的中间件来处理。但我认为这不利于MVC,我在真实项目中采用了其他的做法讲路由和控制层分离。

3.接下来写api.js

var express = require(‘express’); var router = express.Router(); router.get(‘/’, function(req, res) { if (req.query && req.query.callback) { //console.log(params.query.callback); res.jsonp({status: 200, message: “这是一个JSONP接口”, data:[]}); } else { res.json({status: 200, message: “这是一个JSON接口”, data:[]}); } }); module.exports = router;

服务器端已经完毕,这是一种GET的请求方式,req.query是URL里面的参数。我是直接采用express官方的写法来写的,实际用node.js也数行代码。单鞋原生的对http头会有一种新的理解。

4.打开客户端写下游览器js,打开view目录下的, index.ejs模板。

<!DOCTYPE html><html>  <head>    <title><%= title %></title>    <link rel='stylesheet' href='/stylesheets/style.css' />    <script src="/javascripts/jquery.js"></script>  </head>  <body>    <h1><%= title %></h1>    <p>Welcome to <%= title %></p>    <script type="text/javascript">      function get_jsonp() {        $.getJSON("http://127.0.0.1:3000/api?callback=?",                function(data) {                  $('#rjsonp').val('Jsonp info : ' + data.message);                });        }      function get_json(){        $.getJSON("/api",                function(data) {                  $('#rjson').val('Json info : ' + data.message);                });        }    </script>    <a href="javascript:get_jsonp();">Click me for jsonp</a><br />    <textarea id="rjsonp" cols="50" rows="3"></textarea>    <br />    <a href="javascript:get_json();">Click me for json</a><br />    <textarea id="rjson" cols="50" rows="3"></textarea>  </body></html>

到此结束完毕。打开命令窗口,

npm install

安装node.js依赖包

node bin/www

启动node程序

打开游览器访问http://localhost:3000/

由于时间紧张,很多代码都有没有做太多的讲解。

express框架对于json这个方法的处理

res.json = function json(obj) {  var val = obj;  // allow status / bodyif (arguments.length === 2) {    // res.json(body, status) backwards compatif (typeof arguments[1] === 'number') {      deprecate('res.json(obj, status): Use res.status(status).json(obj) instead');      this.statusCode = arguments[1];    } else {      deprecate('res.json(status, obj): Use res.status(status).json(obj) instead');      this.statusCode = arguments[0];      val = arguments[1];    }  }  // settingsvar app = this.app;  var replacer = app.get('json replacer');  var spaces = app.get('json spaces');  var body = JSON.stringify(val, replacer, spaces);  // content-typeif (!this.get('Content-Type')) {    this.set('Content-Type', 'application/json');  }  return this.send(body);};res.send = function send(body) {  var chunk = body;  var encoding;  var len;  var req = this.req;  var type;  // settingsvar app = this.app;  // allow status / bodyif (arguments.length === 2) {    // res.send(body, status) backwards compatif (typeof arguments[0] !== 'number' && typeof arguments[1] === 'number') {      deprecate('res.send(body, status): Use res.status(status).send(body) instead');      this.statusCode = arguments[1];    } else {      deprecate('res.send(status, body): Use res.status(status).send(body) instead');      this.statusCode = arguments[0];      chunk = arguments[1];    }  }  // disambiguate res.send(status) and res.send(status, num)if (typeof chunk === 'number' && arguments.length === 1) {    // res.send(status) will set status message as text stringif (!this.get('Content-Type')) {      this.type('txt');    }    deprecate('res.send(status): Use res.status(status).end() instead');    this.statusCode = chunk;    chunk = http.STATUS_CODES[chunk];  }  switch (typeof chunk) {    // string defaulting to htmlcase 'string': if (!this.get('Content-Type')) {        this.type('html');      }      break;    case 'boolean': case 'number': case 'object': if (chunk === null) {        chunk = '';      } else if (Buffer.isBuffer(chunk)) {        if (!this.get('Content-Type')) {          this.type('bin');        }      } else {        return this.json(chunk);      }      break;  }  // write strings in utf-8if (typeof chunk === 'string') {    encoding = 'utf8';    type = this.get('Content-Type');    // reflect this in content-typeif (typeof type === 'string') {      this.set('Content-Type', setCharset(type, 'utf-8'));    }  }  // populate Content-Lengthif (chunk !== undefined) {    if (!Buffer.isBuffer(chunk)) {      // convert chunk to Buffer; saves later double conversionschunk = new Buffer(chunk, encoding);      encoding = undefined;    }    len = chunk.length;    this.set('Content-Length', len);  }  // method checkvar isHead = req.method === 'HEAD';  // ETag supportif (len !== undefined && (isHead || req.method === 'GET')) {    var etag = app.get('etag fn');    if (etag && !this.get('ETag')) {      etag = etag(chunk, encoding);      etag && this.set('ETag', etag);    }  }  // freshnessif (req.fresh) this.statusCode = 304;  // strip irrelevant headersif (204 == this.statusCode || 304 == this.statusCode) {    this.removeHeader('Content-Type');    this.removeHeader('Content-Length');    this.removeHeader('Transfer-Encoding');    chunk = '';  }  // skip body for HEADif (isHead) {    this.end();  }  // respondthis.end(chunk, encoding);  return this;};

send方法主要数对输出数据 合理字符串化,node中只允许传输Buffer或者String。

0 0
原创粉丝点击