node.js基础(二):http模块

339 阅读4分钟
  • 支持更多特性
  • 不缓冲响应和请求
  • 处理流相关

一些概念

  • 什么是同步/异步
  • 什么是回调
  • 什么是IO
  • 什么是阻塞/非阻塞
  • 什么是事件
  • 什么是事件驱动
  • 什么是基于事件驱动的回调

什么是同步/异步

同步

举个例子: 打电话预定餐馆有没有位置,餐馆说查询一下,这时你等待 餐馆的查询结果,然后挂电话,这就是一个同步的例子

打电话-等待查询结果-挂电话

同步就是执行任务,后一个任务等待前一个任务执行完成再执行,程序的 执行顺序与任务的排列顺序是一致的

a

var i=0;
while(true){
    i++;
}

console.log(i)

上面是一个死循环,console.log永远也不会执行

异步

也是打电话的例子: 餐馆说“我查一下”,然后就挂电话了,找到结果 再打电话通知你 这里老板是通过回电话这种方式回调 打电话-留号码-查结果-回电话

任务的执行顺序与任务的排列顺序不是一致的,任务通过回调控制流程

javascript最基础的异步函数是:

  • setTimeout
  • setInterval
var c=0;
function printIt(){
    console.log(c)
}

function plus(callback){
    setTimeout(function(){
        c+=1;
        callback();
    },1000)
}

plus(printIt);
console.log(111);

什么是回调

JavaScript 语言对异步编程的实现,就是回调函数。所谓回调函数,就是把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数。

callback.js

function callback(something){
    console.log(something);
}

function we(callback, something){
    setTimeout(function(){
      callback(something);
    }, 300);
    
}

什么是IO

磁盘读写或网络通信(统称为 I/O 操作)通常要耗费较长的时间

基本用法

处理GET请求

http模块主要用于搭建HTTP服务。使用Node搭建HTTP服务器非常简单。

一个http服务器

var http = require('http');

var app = http.createServer(function (request, response){
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
});

app.listen(8080, '127.0.0.1');

console.log('Server running on port 8080.');
  • 调用http模块的createServer方法,创造一个服务器实例。

  • ceateServer方法接受一个函数作为参数,该函数的request参数是一个对象,表示客户端的HTTP请求;response参数也是一个对象,表示服务器端的HTTP回应。

  • response.writeHead方法用来写入HTTP回应的头信息;

  • listen(8080)表示启动服务器实例,监听本机的8080端口。

response.end方法用来写入HTTP回应的具体内容,以及回应完成后关闭本次对话。

返回文件

var http = require('http');
var fs = require('fs');

var app = http.createServer(function (request, response){
  fs.readFile('index.html', function readData(err, data) {
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.end(data);
  });
});

app.listen(8080, '127.0.0.1');

console.log('Server running on port 8080.');

根据不同网址的请求,显示不同的内容



var http = require("http");

http.createServer(function(req, res) {

  // 主页
  if (req.url == "/") {
    res.writeHead(200, { "Content-Type": "text/html" });
    res.end("Welcome to the homepage!");
  }

  // About页面
  else if (req.url == "/about") {
    res.writeHead(200, { "Content-Type": "text/html" });
    res.end("Welcome to the about page!");
  }

  // 404错误
  else {
    res.writeHead(404, { "Content-Type": "text/plain" });
    res.end("404 error! File not found.");
  }

}).listen(8080, "localhost");

回调函数的req(request)对象,拥有以下属性。

  • url:发出请求的网址。
  • method:HTTP请求的方法。
  • headers:HTTP请求的所有HTTP头信息。

处理POST请求

当客户端采用POST方法发送数据时,服务器端可以对data和end两个事件,设立监听函数。

var http = require('http');

http.createServer(function (req, res) {
  var content = "";

  req.on('data', function (chunk) {
    content += chunk;
  });

  req.on('end', function () {
    res.writeHead(200, {"Content-Type": "text/plain"});
    res.write("You've sent: " + content);
    res.end();
  });

}).listen(8080);

data事件会在数据接收过程中,每收到一段数据就触发一次,接收到的数据被传入回调函数。end事件则是在所有数据接收完成后触发。

使用postman做测试

发出请求

request()

request方法用于发出HTTP请求,它的使用格式如下。

http.request(options[, callback])

options对象可以设置如下属性:

  • host:HTTP请求所发往的域名或者IP地址,默认是localhost。
  • port:远程服务器的端口,默认是80。
  • method:指定HTTP请求的方法,格式为字符串,默认为GET。
  • path:指定HTTP请求的路径,默认为根路径(/)。可以在这个属性里面,指定查询字符串,比如/index.html?page=12。如果这个属性里面包含非法字符(比如空格),就会抛出一个错误。
  • headers:一个对象,包含了HTTP请求的头信息。。
var postData = querystring.stringify({
  'msg' : 'Hello World!'
});

var options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': postData.length
  }
};

var req = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});

req.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

// write data to request body
req.write(postData);
req.end();

get

get方法用于发出get请求。

function getTestPersonaLoginCredentials(callback) {
  return http.get({
    host: 'personatestuser.org',
    path: '/email'
  }, function(response) {
    var body = '';

    response.on('data', function(d) {
      body += d;
    });

    response.on('end', function() {
      var parsed = JSON.parse(body);
      callback({
        email: parsed.email,
        password: parsed.pass
      });
    });
  });
}

注意,上面代码中,req.end() 必须被调用,即使没有在请求体内写入任何数据,也必须调用。因为这表示已经完成HTTP请求。

发送过程的任何错误(DNS错误、TCP错误、HTTP解析错误),都会在request对象上触发error事件。