Node入门

服务端JavaScript

JavaScript最先是运行在浏览器上的,浏览器只是提供了一个上下文,它定义了JavaScript能够作什么,并无指明JavaScript语言自己能够作什么,实际上,JavaScript是一门完整的语言,能够使用在不一样的上下文中,要实如今后台运行JavaScript代码,代码须要先被解释而后执行,Node.js的原理就是如此,他使用Google的V8虚拟机来解释和执行JavaScript代码,所以,NodeJs事实上既是一个运行时环境,同时又是一个库。javascript

Node.js的Web应用

一个基础的HTTP服务器

新建一个server.js文件并写入以下代码:java

var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);

使用Node.js执行脚本node

node server.js

在浏览器访问http://localhost:8888/,能够看到网页。web

用这样的代码也能够实现:浏览器

var http = require("http");

function onRequest(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}

http.createServer(onRequest).listen(8888);

基于事件驱动的回调

var http = require("http");

function onRequest(request, response) {
  console.log("Request received.");
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}

http.createServer(onRequest).listen(8888);

console.log("Server has started.");

运行后,会立刻在命令行输出“Server has started”,在浏览器输入地址访问后(发出请求),“Request has received.”就会在命令行中出现。服务器

模块化

var http = require("http");

function start() {
  function onRequest(request, response) {
    console.log("Request received.");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

咱们如今就能够建立咱们的主文件 index.js 并在其中启动咱们的HTTP了,虽然服务器的代码还在 server.js 中。模块化

建立 index.js 文件并写入如下内容:函数

var server = require("./server");

server.start();

请求的路由

请求的数据都回包含在request对象,该对象做为onRequest()回调函数的第一个参数传递,为了解析这些数据,咱们须要url模块和queryString模块。ui

url.parse(string).query
                                           |
           url.parse(string).pathname      |
                       |                   |
                       |                   |
                     ------ -------------------
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
              querystring(string)["foo"]    |
                                            |
                         querystring(string)["hello"]

改server.js为以下:url

var http = require("http");
var url = require("url");

function start() {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

如今咱们编写路由,建一个route.js文件以下:

function route(pathname) {
  console.log("About to route a request for " + pathname);
}

exports.route = route;

扩展server.js以整合路由:

var http = require("http");
var url = require("url");

function start(route) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    route(pathname);

    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

同时,咱们会相应扩展index.js,使得路由函数能够被注入到服务器中:

var server = require("./server");
var router = require("./router");

server.start(router.route);

路由给真正的请求处理程序

建立一个requestHandlers模块,并对于每个请求处理程序,添加一个占位用函数,并导出

function start() {
  console.log("Request handler 'start' was called.");
}

function upload() {
  console.log("Request handler 'upload' was called.");
}

exports.start = start;
exports.upload = upload;

扩展index.js

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;

server.start(router.route, handle);

修改server.js

var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    route(handle, pathname);

    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

修改route.js

function route(handle, pathname) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === 'function') {
    handle[pathname]();
  } else {
    console.log("No request handler found for " + pathname);
  }
}

exports.route = route;

很差的实现方式

让请求处理程序经过onRequest函数直接返回(return())他们要展现给用户的信息。

咱们先就这样去实现,而后再来看为何这不是一种很好的实现方式。

requestHandler.js修改成以下形式:

function start() {
  console.log("Request handler 'start' was called.");
  return "Hello Start";
}

function upload() {
  console.log("Request handler 'upload' was called.");
  return "Hello Upload";
}

exports.start = start;
exports.upload = upload;

一样的,请求路由须要将请求处理程序返回给它的信息返回给服务器。所以,咱们须要将router.js修改成以下形式:

function route(handle, pathname) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === 'function') {
    return handle[pathname]();
  } else {
    console.log("No request handler found for " + pathname);
    return "404 Not found";
  }
}

exports.route = route;

最后,咱们须要对咱们的server.js进行重构以使得它可以将请求处理程序经过请求路由返回的内容响应给浏览器,以下所示:

var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    response.writeHead(200, {"Content-Type": "text/plain"});
    var content = route(handle, pathname)
    response.write(content);
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

若是咱们运行重构后的应用,一切都会工做的很好:请求http://localhost:8888/start,浏览器会输出“Hello Start”,请求http://localhost:8888/upload会输出“Hello Upload”,而请求http://localhost:8888/foo 会输出“404 Not found”。

相关文章
相关标签/搜索