Node.js

Node.js简介

  • Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时
  • Node.js没有web容器
  • Node.js的特点(面试必考)
  1. 单线程
  2. 非阻塞I/O
  3. 事件驱动
  • 单线程
    NodeJs不为每个用户创建一个新的线程,而仅仅使用一个线程,当有用户连接了,就触发了一个内部事件,通过非阻塞I/O,事件驱动机制,让Node.js程序宏观上也是并行的,使用Node.js,一个8GB内存的服务器,可以同时处理超过4万用户的连接

  • 非阻塞I/O

  1. Node.js中采用了非阻塞型I/O机制,因此在执行了访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提高程序的执行效率
  2. 当某个I/O执行完毕后,将以事件的形式通知执行I/O操作的线程,线程执行这个事件的回调函数,为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理
  • 事件驱动
    在Node中,客户端请求建立连接,提交数据等行为,会触发相应的事件,在Node中,在一个时刻,只能执行一个回调函数,但是在执行一个事件回调函数的中途,可以转而处理其他事件(比如,新用户连接了),然后返回继续执行原事件的回调函数.这种处理机制,称谓"事件环"机制

Hello world

// 引包-特殊的功能模块
const http = require("http");
// 创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么
const server = http.createServer((req, res) => {
  res.writeHead(200, { "content-type": "text/html;chartset=UTF-8" });
  res.end("Hello World !");
});
server.listen(3000, (err) => {
  if (err) {
    throw err;
  }
  console.log("启动服务器成功");
});

  • res.writeHead(参数一,参数二)
  1. 参数一:状态码
  2. 参数二:响应头对象

在这里插入图片描述

Node.js没有Web容器的概念

  • node.js本质上上没有web容器的,在学习PHP中,web容器放在apache中,举例:将app.html放置在apache中,可以通过地址栏http://localhost:3000/app.html访问该页面,而在node.js中不存在像apache这种web容器,不能通过地址栏访问对应的页面地址来访问页面,只能通过请求返回对应的页面数据
  • Node.js本质上是没有web容器的,不存在把一个页面做好后放到一个文件夹里,Node.js可以直接呈现它
  • 路径(url)与文件无关

Node.js呈现一个页面

const http = require("http");
const fs = require("fs");
const path = require("path");
const server = http.createServer((req, res) => {
  fs.readFile(path.join(__dirname, "index.html"), (err, data) => {
    if (err) {
      throw err;
    }
    res.writeHead(200, { "content-type": "text/html;chartset=UTF-8" });
    res.end(data);
  });
});
server.listen(3000, (err) => {
  if (err) {
    throw err;
  }
  console.log("启动服务器成功");
});

  • fs模块读取页面内容,然后将该内容返回给客户端
    在这里插入图片描述
  • 我们在浏览器地址栏输入不同的地址,我们可以得到不同的页面展示,在apache中我们如果想要访问app.html页面,我们必须老老实实的输入http://localhost:3000/app.html,而在node.js中可以直接完成顶层路由设计,输入的URL跟我们绑定的页面没有直接关系,通过URL根本判断不了我们文件存在哪个地方,这种映射关系由我们在node中的相关逻辑代码来实现

页面中含有图片

在这里插入图片描述

  • 我们在返回的页面中引入一张图片
    在这里插入图片描述
  • 发现图片加载失败,因为图片也是要发送请求的,而我们没有处理该请求的相关逻辑
    在这里插入图片描述
  • 在代码中写相关逻辑
    在这里插入图片描述
    在这里插入图片描述

导入外部的样式表(或者js文件)

  • 导入外部的样式表或者js文件都是要发送请求的
    在这里插入图片描述
    在这里插入图片描述
  • 晚上index.css请求的相关逻辑代码
    在这里插入图片描述
    在这里插入图片描述
  • Node.js虽然没有像Apache那样简单,需要自己写相关代码实现访问静态文件,但这个模式可以使我们写出非常具有扩展性的路由设计,顶层路由设计

http模块简单讲解

  • 服务器监听可以第二个参数可以传ip
server.listen(3000, "127.0.0.1", (err) => {
  if (err) {
    throw err;
  }
  console.log("启动服务器成功");
});
  • 设置响应头 text.html和text/plain (告诉浏览器如何处理返回的数据)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • res.end(data) data不许是一个字符串或者Buffer

url模块

req.url简介

在这里插入图片描述

  • 在地址栏中输入url(不带锚点#)
    在这里插入图片描述
  • 控制台输出( / 代表根路径 )
    在这里插入图片描述
  • 在地址栏中输入url(带锚点#)
    在这里插入图片描述
  • 小结:地址栏输入的url(不管有没有锚点),在服务器的req.url都不带锚点

识别req.url

  • 用到两个模块,url模块querystring模块
  • querystring:查询字符串,是url问号?后面的东西(不包括问号),所以需要先将url中问号后面的字符串提取出来,这个时候就需要用到url模块
    在这里插入图片描述
    在这里插入图片描述
  • 最重要的是url.parse()/querystring.parse()

demo1 地址栏输入

  • 在地址栏中输入
    在这里插入图片描述
  • 控制台输出
    在这里插入图片描述
  • 因为req.url不包含hash(锚点),所以parse出来的对象,hash属性为null

demo2 表单提交

  • 本地(不在服务器上)表单提交
    在这里插入图片描述
  • node服务器输入urlObj
    在这里插入图片描述
  • 然后通过querystring模块通过querystring.parse()得到一个对象,里面包含name和age属性

Node.js服务器的缺点

  • 缓存问题:通常第二次访问同一文件,会返回304,而我们现在刷新,返回的状态码永远是200
    在这里插入图片描述
  • 这个时候就需要cookies打标记,然后检测文件的lastModify属性(最后更改信息),判断是否需要判断状态码304
  • 即304状态码不是自动的,需要自己写相关逻辑代码(apache返回的状态码304是自动的,不需要写相关逻辑代码)
  • Apache服务器和Node服务器各有 优缺点,Apache内部完成了大量代码判断和逻辑,不需要开发人员写逻辑代码,Node服务器虽然需要开发人员写相关逻辑代码判断,但也实现了路由顶层设计,更加灵活

Post请求

  • get请求的参数在url上,可以通过url模块和querystring模块取到参数对象
  • 相比较get请求,post请求比较复杂,因为node.js认为,使用post请求时,数据量会比较多,为了追求数据极致的效率,它将数据拆分为了众多小的数据块(chunk),然后通过特定的事件,将这些小数据块有序传递给回调函数

demo

  • 本地创建一个表单页面
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form action="http://127.0.0.1:3000/dopost" method="POST">
      <label>姓名</label>
      <input type="text" name="name" />
      <label>年龄</label>
      <input type="text" name="age" />
      <input type="submit" />
    </form>
  </body>
</html>
  • 创建服务器
const http = require("http");
const url = require("url");
const server = http.createServer((req, res) => {
  if (req.url === "/dopost" && req.method.toLocaleLowerCase() === "post") {
    var data = ""; // 空串
    // 接收数据
    req.on("data", (chunk) => {
      data += chunk;
    });
    // 数据完成接收
    req.on("end", () => {
      console.log(data); // 字符串
    });
  }
});
server.listen(3000, "127.0.0.1", (err) => {
  if (err) {
    throw err;
  }
  console.log("启动服务器成功");
});

在这里插入图片描述

  • 最重要的是两个事件:data事件和end事件
  • get请求和post请求提交的数据都是字符串,所以上面案例中data最终也是字符串
  • 在ajax中ge/post请求也是字符串,和node服务对应起来了
    在这里插入图片描述
  • 利用querystring模块将data字符串转换成对象
    在这里插入图片描述

文件上传 formidable包

  • formidable是用于上传文件或者视频的第三方包
    在这里插入图片描述
  • formidable实例的parse方法内部帮助我们实现了数据的收集
  1. fields:所有的表单域数据
  2. files:所有的文件域数据
  • formidable实例.parse(参数一,参数二)
  1. 参数一: req,请求报文
  2. 参数二:回调函数
    2.1 参数2.1: err 错误优先
    2.2 参数2.2: fields 所有的表单域数据
    2.3 参数2.3: files 所有的文件域数据
  • 在本地表单页面中
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form
      action="http://127.0.0.1:3000/dopost"
      enctype="multipart/form-data"
      method="POST"
    >
      <label>姓名</label>
      <input type="text" name="name" />
      <label>年龄</label>
      <input type="text" name="age" />
      <label>文件</label>
      <input type="file" name="file" />
      <input type="submit" />
    </form>
  </body>
</html>
  • 在node服务器中
    在这里插入图片描述
  • 此时我们为什么看到的fiels是一个空对象呢,是因为上传的文件还没到node服务器,只是保存在本地c盘的缓存中,我们需要将文件从本地缓存放置到服务器中,只需要在服务器中设置保存上传文件的地址即可
    在这里插入图片描述
  • files对象最重要的是path属性和name属性
  • 发现上传的文件没有后缀名,且文件名是一个hash值(path属性)(不是原文件名name属性)
  • 实现上传文件重命名 fs.rename()
    在这里插入图片描述
    在这里插入图片描述

表单post提交enctype="multipart/form-data"属性的作用

  • 表单不设置该属性
    在这里插入图片描述
    在这里插入图片描述

  • 设置了该属性,文件以碎片化方式传输
    在这里插入图片描述
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值