Node.js:GET/POST请求、路由

来自Wikioe
跳到导航 跳到搜索


GET/POST请求

在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交。

表单提交到服务器一般都使用 GET/POST 请求。

获取 GET 请求内容

由于 GET 请求直接被嵌入在路径中,URL是完整的请求路径,包括了“?”后面的部分,因此可以手动解析后面的内容作为 GET 请求的参数。


node.js 中 url 模块中的 parse 函数提供了这个功能,示例:

var http = require('http');
var url = require('url');
var util = require('util');
 
http.createServer(function(request, response){
    response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    response.end(util.inspect(url.parse(request.url, true)));
}).listen(3000);

在浏览器中访问 http://localhost:3000/user?name=菜鸟教程&url=www.runoob.com 然后查看返回结果:

Node.js:获取 GET 请求内容.png

获取 URL 的参数

可以使用 url.parse 方法来解析 URL 中的参数,代码如下:

var http = require('http');
var url = require('url');
var util = require('util');
 
http.createServer(function(request, response){
    // 解析 url 参数
    var params = url.parse(request.url, true).query;
    
    response.writeHead(200, {'Content-Type': 'text/plain'});
    response.write("网站名:" + params.name);
    response.write("\n");
    response.write("网站 URL:" + params.url);
    response.end();
}).listen(3000);

在浏览器中访问 http://localhost:3000/user?name=菜鸟教程&url=www.runoob.com 然后查看返回结果:

Node.js:获取 URL 的参数.png

获取 POST 请求内容

POST 请求的内容全部的都在请求体中,http.ServerRequest 并没有一个属性内容为请求体,原因是等待请求体传输可能是一件耗时的工作,比如上传文件。

而很多时候我们可能并不需要理会请求体的内容,恶意的POST请求会大大消耗服务器的资源。所以 node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做。

node.js 默认是不会解析请求体的,需要手动解析:

var http = require('http');
var querystring = require('querystring');
var util = require('util');
 
http.createServer(function(request, response){
    // 定义了一个 post 变量,用于暂存请求体的信息
    var post = '';     
 
    // 通过 request 的 data 事件监听函数,每当接受到请求体的数据,就累加到 post 变量中
    request.on('data', function(chunk){    
        post += chunk;
    });
 
    // 在 end 事件触发后,通过 querystring.parse 将 post 解析为真正的 POST 请求格式,然后向客户端返回。
    request.on('end', function(){    
        post = querystring.parse(post);
        response.end(util.inspect(post));
    });
}).listen(3000);


示例:表单通过 POST 提交并输出数据:

var http = require('http');
var querystring = require('querystring');
 
var postHTML = 
  '<html><head><meta charset="utf-8"><title>菜鸟教程 Node.js 实例</title></head>' +
  '<body>' +
  '<form method="post">' +
  '网站名: <input name="name"><br>' +
  '网站 URL: <input name="url"><br>' +
  '<input type="submit">' +
  '</form>' +
  '</body></html>';
 
http.createServer(function (request, response) {
  var body = "";
  request.on('data', function (chunk) {
    body += chunk;
  });
  request.on('end', function () {
    // 解析参数
    body = querystring.parse(body);
    // 设置响应头部信息及编码
    response.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});
 
    if(body.name && body.url) { // 输出提交的数据
        response.write("网站名:" + body.name);
        response.write("<br>");
        response.write("网站 URL:" + body.url);
    } else {  // 输出表单
        response.write(postHTML);
    }
    response.end();
  });
}).listen(3000);

执行结果 Gif 演示:

Node.js:获取 POST 请求内容.gif

路由【???】

我们要为路由提供请求的 URL 和其他需要的 GET 及 POST 参数,随后路由需要根据这些数据来执行相应的代码。

因此,我们需要查看 HTTP 请求,从中提取出请求的 URL 以及 GET/POST 参数。
  这一功能应当属于路由还是服务器(甚至作为一个模块自身的功能)确实值得探讨,但这里暂定其为我们的HTTP服务器的功能。

我们需要的所有数据都会包含在 request 对象中,该对象作为 onRequest() 回调函数的第一个参数传递。

但是为了解析这些数据,我们需要额外的 Node.JS 模块:urlquerystring


  1. “server.js”:
    给 onRequest() 函数加上一些逻辑,用来找出浏览器请求的 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;
    
    现在可以通过请求的 URL 路径来区别不同请求了
  2. “router.js”:
    编写路由:
    function route(pathname) {
      console.log("About to route a request for " + pathname);
    }
     
    exports.route = route;
    
  3. 整合:
    • 使用依赖注入的方式较松散地添加路由模块(可以但不推荐硬通过硬编码的方式将这一依赖项绑定到服务器上)
    1. 服务器(“server.js”)应当知道路由(“router.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;
      
    2. 扩展“index.js”,使得路由函数可以被注入到服务器中:
      var server = require("./server");
      var router = require("./router");
       
      server.start(router.route);
      

现在启动应用(node index.js,始终记得这个命令行),随后请求一个 URL,将会看到应用输出相应的信息,这表明我们的 HTTP 服务器已经在使用路由模块了,并会将请求的路径传递给路由:

$ node index.js
Server has started.

浏览器访问 http://127.0.0.1:8888/ ,输出结果如下:

Node.js:路由示例.png