1. 程式人生 > >node.js學習(七、express框架建立api介面)

node.js學習(七、express框架建立api介面)

根據官方文件,用如下方式構造請求:

   app.get("/login/:username/:password",function (req, res) {   
    console.log(req);
   res.send("get it");
}); 

在get的路徑引數中填寫請求路徑,其中請求需要的引數用/:引數名錶示。如上req代表請求資料,res代表伺服器返回給瀏覽器的資料。那麼伺服器如何獲取請求的引數呢,不妨列印一下req物件。上傳程式碼至伺服器,node app.js執行。瀏覽器請求http://goodboy.ren:3000/login/name/123,返回get it代表請求成功。此時檢視伺服器,列印如下一段:

    IncomingMessage {
  _readableState: 
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: [],
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: null,
     ended: false,
     endEmitted: false,
     reading: false,
     sync: true,
     needReadable: false
, emittedReadable: false, readableListening: false, resumeScheduled: false, defaultEncoding: 'utf8', ranOut: false, awaitDrain: 0, readingMore: false, decoder: null, encoding: null }, readable: true, domain: null, _events: {}, _eventsCount: 0, _maxListeners: undefined
, socket: Socket { _connecting: false, _hadError: false, _handle: TCP { _externalStream: {}, fd: 12, reading: true, owner: [Circular], onread: [Function: onread], onconnection: null, writeQueueSize: 0 }, _parent: null, _host: null, _readableState: ReadableState { objectMode: false, highWaterMark: 16384, buffer: [], length: 0, pipes: null, pipesCount: 0, flowing: true, ended: false, endEmitted: false, reading: true, sync: false, needReadable: true, emittedReadable: false, readableListening: false, resumeScheduled: false, defaultEncoding: 'utf8', ranOut: false, awaitDrain: 0, readingMore: false, decoder: null, encoding: null }, readable: true, domain: null, _events: { end: [Object], finish: [Function: onSocketFinish], _socketEnd: [Function: onSocketEnd], drain: [Object], timeout: [Function], error: [Function: socketOnError], close: [Object], data: [Function: socketOnData], resume: [Function: onSocketResume], pause: [Function: onSocketPause] }, _eventsCount: 10, _maxListeners: undefined, _writableState: WritableState { objectMode: false, highWaterMark: 16384, needDrain: false, ending: false, ended: false, finished: false, decodeStrings: false, defaultEncoding: 'utf8', length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function], writecb: null, writelen: 0, bufferedRequest: null, lastBufferedRequest: null, pendingcb: 0, prefinished: false, errorEmitted: false, bufferedRequestCount: 0, corkedRequestsFree: [Object] }, writable: true, allowHalfOpen: true, destroyed: false, bytesRead: 0, _bytesDispatched: 0, _sockname: null, _pendingData: null, _pendingEncoding: '', server: Server { domain: null, _events: [Object], _eventsCount: 3, _maxListeners: undefined, _connections: 1, _handle: [Object], _usingSlaves: false, _slaves: [], _unref: false, allowHalfOpen: true, pauseOnConnect: false, httpAllowHalfOpen: false, timeout: 120000, _pendingResponseData: 0, _connectionKey: '4:0.0.0.0:3000' }, _server: Server { domain: null, _events: [Object], _eventsCount: 3, _maxListeners: undefined, _connections: 1, _handle: [Object], _usingSlaves: false, _slaves: [], _unref: false, allowHalfOpen: true, pauseOnConnect: false, httpAllowHalfOpen: false, timeout: 120000, _pendingResponseData: 0, _connectionKey: '4:0.0.0.0:3000' }, _idleTimeout: 120000, _idleNext: { _idleNext: [Circular], _idlePrev: [Circular] }, _idlePrev: { _idleNext: [Circular], _idlePrev: [Circular] }, _idleStart: 7105, parser: HTTPParser { '0': [Function: parserOnHeaders], '1': [Function: parserOnHeadersComplete], '2': [Function: parserOnBody], '3': [Function: parserOnMessageComplete], '4': [Function: onParserExecute], _headers: [], _url: '', _consumed: true, socket: [Circular], incoming: [Circular], outgoing: null, maxHeaderPairs: 2000, onIncoming: [Function: parserOnIncoming] }, on: [Function: socketOnWrap], _paused: false, read: [Function], _consuming: true, _httpMessage: ServerResponse { domain: null, _events: [Object], _eventsCount: 1, _maxListeners: undefined, output: [], outputEncodings: [], outputCallbacks: [], outputSize: 0, writable: true, _last: false, chunkedEncoding: false, shouldKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: true, _removedHeader: {}, _contentLength: null, _hasBody: true, _trailer: '', finished: false, _headerSent: false, socket: [Circular], connection: [Circular], _header: null, _headers: [Object], _headerNames: [Object], _onPendingData: [Function: updateOutgoingData], req: [Circular], locals: {} } }, connection: Socket { _connecting: false, _hadError: false, _handle: TCP { _externalStream: {}, fd: 12, reading: true, owner: [Circular], onread: [Function: onread], onconnection: null, writeQueueSize: 0 }, _parent: null, _host: null, _readableState: ReadableState { objectMode: false, highWaterMark: 16384, buffer: [], length: 0, pipes: null, pipesCount: 0, flowing: true, ended: false, endEmitted: false, reading: true, sync: false, needReadable: true, emittedReadable: false, readableListening: false, resumeScheduled: false, defaultEncoding: 'utf8', ranOut: false, awaitDrain: 0, readingMore: false, decoder: null, encoding: null }, readable: true, domain: null, _events: { end: [Object], finish: [Function: onSocketFinish], _socketEnd: [Function: onSocketEnd], drain: [Object], timeout: [Function], error: [Function: socketOnError], close: [Object], data: [Function: socketOnData], resume: [Function: onSocketResume], pause: [Function: onSocketPause] }, _eventsCount: 10, _maxListeners: undefined, _writableState: WritableState { objectMode: false, highWaterMark: 16384, needDrain: false, ending: false, ended: false, finished: false, decodeStrings: false, defaultEncoding: 'utf8', length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function], writecb: null, writelen: 0, bufferedRequest: null, lastBufferedRequest: null, pendingcb: 0, prefinished: false, errorEmitted: false, bufferedRequestCount: 0, corkedRequestsFree: [Object] }, writable: true, allowHalfOpen: true, destroyed: false, bytesRead: 0, _bytesDispatched: 0, _sockname: null, _pendingData: null, _pendingEncoding: '', server: Server { domain: null, _events: [Object], _eventsCount: 3, _maxListeners: undefined, _connections: 1, _handle: [Object], _usingSlaves: false, _slaves: [], _unref: false, allowHalfOpen: true, pauseOnConnect: false, httpAllowHalfOpen: false, timeout: 120000, _pendingResponseData: 0, _connectionKey: '4:0.0.0.0:3000' }, _server: Server { domain: null, _events: [Object], _eventsCount: 3, _maxListeners: undefined, _connections: 1, _handle: [Object], _usingSlaves: false, _slaves: [], _unref: false, allowHalfOpen: true, pauseOnConnect: false, httpAllowHalfOpen: false, timeout: 120000, _pendingResponseData: 0, _connectionKey: '4:0.0.0.0:3000' }, _idleTimeout: 120000, _idleNext: { _idleNext: [Circular], _idlePrev: [Circular] }, _idlePrev: { _idleNext: [Circular], _idlePrev: [Circular] }, _idleStart: 7105, parser: HTTPParser { '0': [Function: parserOnHeaders], '1': [Function: parserOnHeadersComplete], '2': [Function: parserOnBody], '3': [Function: parserOnMessageComplete], '4': [Function: onParserExecute], _headers: [], _url: '', _consumed: true, socket: [Circular], incoming: [Circular], outgoing: null, maxHeaderPairs: 2000, onIncoming: [Function: parserOnIncoming] }, on: [Function: socketOnWrap], _paused: false, read: [Function], _consuming: true, _httpMessage: ServerResponse { domain: null, _events: [Object], _eventsCount: 1, _maxListeners: undefined, output: [], outputEncodings: [], outputCallbacks: [], outputSize: 0, writable: true, _last: false, chunkedEncoding: false, shouldKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: true, _removedHeader: {}, _contentLength: null, _hasBody: true, _trailer: '', finished: false, _headerSent: false, socket: [Circular], connection: [Circular], _header: null, _headers: [Object], _headerNames: [Object], _onPendingData: [Function: updateOutgoingData], req: [Circular], locals: {} } }, httpVersionMajor: 1, httpVersionMinor: 1, httpVersion: '1.1', complete: false, headers: { host: 'goodboy.ren:3000', connection: 'keep-alive', 'cache-control': 'max-age=0', accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36', 'accept-encoding': 'gzip, deflate, sdch', 'accept-language': 'zh-CN,zh;q=0.8' }, rawHeaders: [ 'Host', 'goodboy.ren:3000', 'Connection', 'keep-alive', 'Cache-Control', 'max-age=0', 'Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Upgrade-Insecure-Requests', '1', 'User-Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36', 'Accept-Encoding', 'gzip, deflate, sdch', 'Accept-Language', 'zh-CN,zh;q=0.8' ], trailers: {}, rawTrailers: [], upgrade: false, url: '/login/name/123', method: 'GET', statusCode: null, statusMessage: null, client: Socket { _connecting: false, _hadError: false, _handle: TCP { _externalStream: {}, fd: 12, reading: true, owner: [Circular], onread: [Function: onread], onconnection: null, writeQueueSize: 0 }, _parent: null, _host: null, _readableState: ReadableState { objectMode: false, highWaterMark: 16384, buffer: [], length: 0, pipes: null, pipesCount: 0, flowing: true, ended: false, endEmitted: false, reading: true, sync: false, needReadable: true, emittedReadable: false, readableListening: false, resumeScheduled: false, defaultEncoding: 'utf8', ranOut: false, awaitDrain: 0, readingMore: false, decoder: null, encoding: null }, readable: true, domain: null, _events: { end: [Object], finish: [Function: onSocketFinish], _socketEnd: [Function: onSocketEnd], drain: [Object], timeout: [Function], error: [Function: socketOnError], close: [Object], data: [Function: socketOnData], resume: [Function: onSocketResume], pause: [Function: onSocketPause] }, _eventsCount: 10, _maxListeners: undefined, _writableState: WritableState { objectMode: false, highWaterMark: 16384, needDrain: false, ending: false, ended: false, finished: false, decodeStrings: false, defaultEncoding: 'utf8', length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function], writecb: null, writelen: 0, bufferedRequest: null, lastBufferedRequest: null, pendingcb: 0, prefinished: false, errorEmitted: false, bufferedRequestCount: 0, corkedRequestsFree: [Object] }, writable: true, allowHalfOpen: true, destroyed: false, bytesRead: 0, _bytesDispatched: 0, _sockname: null, _pendingData: null, _pendingEncoding: '', server: Server { domain: null, _events: [Object], _eventsCount: 3, _maxListeners: undefined, _connections: 1, _handle: [Object], _usingSlaves: false, _slaves: [], _unref: false, allowHalfOpen: true, pauseOnConnect: false, httpAllowHalfOpen: false, timeout: 120000, _pendingResponseData: 0, _connectionKey: '4:0.0.0.0:3000' }, _server: Server { domain: null, _events: [Object], _eventsCount: 3, _maxListeners: undefined, _connections: 1, _handle: [Object], _usingSlaves: false, _slaves: [], _unref: false, allowHalfOpen: true, pauseOnConnect: false, httpAllowHalfOpen: false, timeout: 120000, _pendingResponseData: 0, _connectionKey: '4:0.0.0.0:3000' }, _idleTimeout: 120000, _idleNext: { _idleNext: [Circular], _idlePrev: [Circular] }, _idlePrev: { _idleNext: [Circular], _idlePrev: [Circular] }, _idleStart: 7105, parser: HTTPParser { '0': [Function: parserOnHeaders], '1': [Function: parserOnHeadersComplete], '2': [Function: parserOnBody], '3': [Function: parserOnMessageComplete], '4': [Function: onParserExecute], _headers: [], _url: '', _consumed: true, socket: [Circular], incoming: [Circular], outgoing: null, maxHeaderPairs: 2000, onIncoming: [Function: parserOnIncoming] }, on: [Function: socketOnWrap], _paused: false, read: [Function], _consuming: true, _httpMessage: ServerResponse { domain: null, _events: [Object], _eventsCount: 1, _maxListeners: undefined, output: [], outputEncodings: [], outputCallbacks: [], outputSize: 0, writable: true, _last: false, chunkedEncoding: false, shouldKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: true, _removedHeader: {}, _contentLength: null, _hasBody: true, _trailer: '', finished: false, _headerSent: false, socket: [Circular], connection: [Circular], _header: null, _headers: [Object], _headerNames: [Object], _onPendingData: [Function: updateOutgoingData], req: [Circular], locals: {} } }, _consuming: false, _dumped: false, next: [Function: next], baseUrl: '', originalUrl: '/login/name/123', _parsedUrl: Url { protocol: null, slashes: null, auth: null, host: null, port: null, hostname: null, hash: null, search: null, query: null, pathname: '/login/name/123', path: '/login/name/123', href: '/login/name/123', _raw: '/login/name/123' }, params: { username: 'name', password: '123' }, query: {}, res: ServerResponse { domain: null, _events: { finish: [Function: resOnFinish] }, _eventsCount: 1, _maxListeners: undefined, output: [], outputEncodings: [], outputCallbacks: [], outputSize: 0, writable: true, _last: false, chunkedEncoding: false, shouldKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: true, _removedHeader: {}, _contentLength: null, _hasBody: true, _trailer: '', finished: false, _headerSent: false, socket: Socket { _connecting: false, _hadError: false, _handle: [Object], _parent: null, _host: null, _readableState: [Object], readable: true, domain: null, _events: [Object], _eventsCount: 10, _maxListeners: undefined, _writableState: [Object], writable: true, allowHalfOpen: true, destroyed: false, bytesRead: 0, _bytesDispatched: 0, _sockname: null, _pendingData: null, _pendingEncoding: '', server: [Object], _server: [Object], _idleTimeout: 120000, _idleNext: [Object], _idlePrev: [Object], _idleStart: 7105, parser: [Object], on: [Function: socketOnWrap], _paused: false, read: [Function], _consuming: true, _httpMessage: [Circular] }, connection: Socket { _connecting: false, _hadError: false, _handle: [Object], _parent: null, _host: null, _readableState: [Object], readable: true, domain: null, _events: [Object], _eventsCount: 10, _maxListeners: undefined, _writableState: [Object], writable: true, allowHalfOpen: true, destroyed: false, bytesRead: 0, _bytesDispatched: 0, _sockname: null, _pendingData: null, _pendingEncoding: '', server: [Object], _server: [Object], _idleTimeout: 120000, _idleNext: [Object], _idlePrev: [Object], _idleStart: 7105, parser: [Object], on: [Function: socketOnWrap], _paused: false, read: [Function], _consuming: true, _httpMessage: [Circular] }, _header: null, _headers: { 'x-powered-by': 'Express' }, _headerNames: { 'x-powered-by': 'X-Powered-By' }, _onPendingData: [Function: updateOutgoingData], req: [Circular], locals: {} }, route: Route { path: '/login/:username/:password', stack: [ [Object] ], methods: { get: true } } }

這裡即為請求大全部資訊,仔細查詢發現一行
params: { username: ‘name’, password: ‘123’ }
這就是我們要或取的值,由此可知get請求的引數是放在params屬性中,通過req.params即可獲取引數物件。

通過以下程式碼測試一下:

  app.get("/login/:username/:password",function (req, res) {    
      var user=req.params;
      var ret="get userinfo username="+user.username+",password="+user.password;
      res.send(ret);
  });

執行程式碼再次請求,返回get userinfo username=name,password=123。說明獲取到了所以的請求引數。實際開發過程中,還須對相應的引數進行處理再返回需要的資料。後續章節會進行講述。

以上為get請求方式獲取資料。當我們需要傳送大量資料時,不得不使用post方式提交資料。那麼post方法如何獲得請求引數,複製開始的程式碼,修改一下,如下:

app.get("/login/:username/:password",function (req, res) {  
   var user=req.params;
   var ret="get userinfo username="+user.username+",password="+user.password;
   res.send(ret);
});


app.post("/login",function (req, res) { 
   console.log(req);
   res.send("post success");
});

按上圖填寫後點擊發生請求按鈕,返回post success。
通過列印日誌發現,請求引數沒有在列印的日誌中。
這時我們需要藉助第三方模組body-parser,git地址為https://github.com/expressjs/body-parser
裡面有詳細的使用說明,按照說明中的例子修改後完整程式碼如下:

var express=require('express');
var app=express();

var bodyParser = require('body-parser')

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

app.get("/sayhello",function (req, res) {   
   res.send('Hello World!');
});


app.get("/login/:username/:password",function (req, res) {  
   var user=req.params;
   var ret="get userinfo username="+user.username+",password="+user.password;
   res.send(ret);
});


app.post("/login",function (req, res) {       
      var user=req.body;
      console.log(user);
      var ret="get userinfo username="+user.username+",password="+user.password;
      res.send(ret);
  });


var server = app.listen(3000);

執行後報錯
Error: Cannot find module ‘body-parser’
at Function.Module._resolveFilename (module.js:325:15)
at Function.Module._load (module.js:276:25)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object. (/data/nodeweb/app.js:4:18)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)

以上錯誤代表沒有下載安裝body-parser包,使用npm install -g body-parser 命令安裝。安裝完成後,執行node app.js。再次通過瀏覽器請求,獲得返回結果。
這裡寫圖片描述

大功告成。下篇記錄如何使用mysql記錄請求資料或者查詢資料。