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

 对于express 新手来说,我推荐一个 express脚手架工具。
  1. npm install -g express-generator

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

  1. exress -e myapp

生成一个express的框架(参数e代表使用ejs模板,默认是jade模板)

 

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

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

2.打开app.js, 在

  1. var users = require('./routes/users');

后面添加

  1. var api = require('./routes/api');

  1. app.use('/users', users);

后面添加

  1. app.use('/api', api);

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

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

3.接下来写api.js

  1. var express = require('express');
  2. var router = express.Router();
  3.  
  4. router.get('/', function(req, res) {
  5. if (req.query && req.query.callback) {
  6. //console.log(params.query.callback);
  7. res.jsonp({status: 200, message: "这是一个JSONP接口", data:[]});
  8. } else {
  9. res.json({status: 200, message: "这是一个JSON接口", data:[]});
  10. }
  11. });
  12.  
  13. module.exports = router;

 

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

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

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title><%= title %></title>
  5. <link rel='stylesheet' href='/stylesheets/style.css' />
  6. <script src="/javascripts/jquery.js"></script>
  7. </head>
  8. <body>
  9. <h1><%= title %></h1>
  10. <p>Welcome to <%= title %></p>
  11. <script type="text/javascript">
  12. function get_jsonp() {
  13. $.getJSON("http://127.0.0.1:3000/api?callback=?",
  14. function(data) {
  15. $('#rjsonp').val('Jsonp info : ' + data.message);
  16. });
  17. }
  18.  
  19. function get_json(){
  20. $.getJSON("/api",
  21. function(data) {
  22. $('#rjson').val('Json info : ' + data.message);
  23. });
  24. }
  25. </script>
  26.  
  27. <a href="javascript:get_jsonp();">Click me for jsonp</a><br />
  28. <textarea id="rjsonp" cols="50" rows="3"></textarea>
  29. <br />
  30.  
  31. <a href="javascript:get_json();">Click me for json</a><br />
  32. <textarea id="rjson" cols="50" rows="3"></textarea>
  33.  
  34. </body>
  35. </html>

 

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

  1. npm install

安装node.js依赖包

 

  1. node bin/www

启动node程序

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

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

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

  1. res.json = function json(obj) {
  2. var val = obj;
  3.  
  4. // allow status / body
  5. if (arguments.length === 2) {
  6. // res.json(body, status) backwards compat
  7. if (typeof arguments[1] === 'number') {
  8. deprecate('res.json(obj, status): Use res.status(status).json(obj) instead');
  9. this.statusCode = arguments[1];
  10. } else {
  11. deprecate('res.json(status, obj): Use res.status(status).json(obj) instead');
  12. this.statusCode = arguments[0];
  13. val = arguments[1];
  14. }
  15. }
  16.  
  17. // settings
  18. var app = this.app;
  19. var replacer = app.get('json replacer');
  20. var spaces = app.get('json spaces');
  21. var body = JSON.stringify(val, replacer, spaces);
  22.  
  23. // content-type
  24. if (!this.get('Content-Type')) {
  25. this.set('Content-Type', 'application/json');
  26. }
  27.  
  28. return this.send(body);
  29. };
  30.  
  31. res.send = function send(body) {
  32. var chunk = body;
  33. var encoding;
  34. var len;
  35. var req = this.req;
  36. var type;
  37.  
  38. // settings
  39. var app = this.app;
  40.  
  41. // allow status / body
  42. if (arguments.length === 2) {
  43. // res.send(body, status) backwards compat
  44. if (typeof arguments[0] !== 'number' && typeof arguments[1] === 'number') {
  45. deprecate('res.send(body, status): Use res.status(status).send(body) instead');
  46. this.statusCode = arguments[1];
  47. } else {
  48. deprecate('res.send(status, body): Use res.status(status).send(body) instead');
  49. this.statusCode = arguments[0];
  50. chunk = arguments[1];
  51. }
  52. }
  53.  
  54. // disambiguate res.send(status) and res.send(status, num)
  55. if (typeof chunk === 'number' && arguments.length === 1) {
  56. // res.send(status) will set status message as text string
  57. if (!this.get('Content-Type')) {
  58. this.type('txt');
  59. }
  60.  
  61. deprecate('res.send(status): Use res.status(status).end() instead');
  62. this.statusCode = chunk;
  63. chunk = http.STATUS_CODES[chunk];
  64. }
  65.  
  66. switch (typeof chunk) {
  67. // string defaulting to html
  68. case 'string':
  69. if (!this.get('Content-Type')) {
  70. this.type('html');
  71. }
  72. break;
  73. case 'boolean':
  74. case 'number':
  75. case 'object':
  76. if (chunk === null) {
  77. chunk = '';
  78. } else if (Buffer.isBuffer(chunk)) {
  79. if (!this.get('Content-Type')) {
  80. this.type('bin');
  81. }
  82. } else {
  83. return this.json(chunk);
  84. }
  85. break;
  86. }
  87.  
  88. // write strings in utf-8
  89. if (typeof chunk === 'string') {
  90. encoding = 'utf8';
  91. type = this.get('Content-Type');
  92.  
  93. // reflect this in content-type
  94. if (typeof type === 'string') {
  95. this.set('Content-Type', setCharset(type, 'utf-8'));
  96. }
  97. }
  98.  
  99. // populate Content-Length
  100. if (chunk !== undefined) {
  101. if (!Buffer.isBuffer(chunk)) {
  102. // convert chunk to Buffer; saves later double conversions
  103. chunk = new Buffer(chunk, encoding);
  104. encoding = undefined;
  105. }
  106.  
  107. len = chunk.length;
  108. this.set('Content-Length', len);
  109. }
  110.  
  111. // method check
  112. var isHead = req.method === 'HEAD';
  113.  
  114. // ETag support
  115. if (len !== undefined && (isHead || req.method === 'GET')) {
  116. var etag = app.get('etag fn');
  117. if (etag && !this.get('ETag')) {
  118. etag = etag(chunk, encoding);
  119. etag && this.set('ETag', etag);
  120. }
  121. }
  122.  
  123. // freshness
  124. if (req.fresh) this.statusCode = 304;
  125.  
  126. // strip irrelevant headers
  127. if (204 == this.statusCode || 304 == this.statusCode) {
  128. this.removeHeader('Content-Type');
  129. this.removeHeader('Content-Length');
  130. this.removeHeader('Transfer-Encoding');
  131. chunk = '';
  132. }
  133.  
  134. // skip body for HEAD
  135. if (isHead) {
  136. this.end();
  137. }
  138.  
  139. // respond
  140. this.end(chunk, encoding);
  141.  
  142. return this;
  143. };
 

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

原文链接:http://www.gbtags.com/gb/share/5530.htm

posted on 2015-06-23 18:05  shirleyqin216  阅读(517)  评论(0)    收藏  举报