一、http模块(需了解web服务器的相关内容)
3.6.1、介绍
Web服务器一般指的是网站服务器(服务器:给用户提供服务的机器就是服务器),是指驻留因特网上某一台或N台计算机的程序,可以处理浏览器等Web客户端的请求并返回相应响应,在服务器上还需要安装服务器软件,目前最主流的三个Web服务器软件是Apache、 Nginx 、IIS。
DNS:动态域名解析系统,作用将域名转化成IP地址
==整理文档(面试题):用户从浏览器打开页面到最终页面呈现在屏幕上,经历了哪些事?==
1.输入URL 2.访问hosts解析 如果没有解析访问DNS解析
3.TCP握手 4.HTTP请求
5.HTTP响应返回数据 6. 浏览器解析并渲染页面
3.6.2、两种开发模式
-
传统开发也叫前后端耦合开发(以前)
-
弊端
-
代码文件都不纯粹,例如写一个前端视图文件,其中可能既有前端代码又有后端代码
-
扩展性不是很好
-
-
优点
-
开发人员的能力好一些
-
-
-
前后端分离开发(现在)
-
优点:
-
不需要前端人员去熟悉后端代码,后端也不用看前端,分工明确自己做自己的事情
-
扩展性好(主要是针对后端),比如:项目多个平台
-
-
缺点:
-
前端所有的数据都来自于网络请求
-
如果用户的网很慢怎么办?
-
网络请求过多怎么办?
-
接口响应过慢怎么办?
-
如何去优化?
-
ajax、promise没学好怎么办?
-
-
-
开发工作流程:需求经理 UI设计师 后台(接口)
3.6.3、服务器相关概念
-
ip地址或域名
ip地址:ip地址有v4和v6之分,IP地址就是互联网上每台计算机/电子设备的唯一地址,因此IP地址具有唯一性。在开发期间,自己的电脑既是一台服务器,也是一个客户端,可以在本机浏览器中输入127.0.0.1进行访问。(IP地址分为公有【用于接入互联网】和私有【组织单元内部的网络,例如:商场、学校、医院、企业等】)
域名:尽管 IP地址能够唯一地标记网络上的计算机,但IP地址是一长串数字,不直观,而且不便于记忆,于是人们又发明了另一套字符型的地址方案,叫域名地址。IP地址和域名是一一对应的关系,这份对应关系存放在一种叫做域名服务器(DNS)的电脑中。在开发测试期间,127.0.0.1 对应的域名是 localhost。
本地如果localhost无法使用,则是因为本机中的hosts文件中没有匹配上ip地址
-
网络协议
网络上的计算机之间交换信息,就像我们说话用某种语言一样,在网络上的各台计算机之间也有一种语言,这就是网络协议,不同的计算机之间必须使用相同的网络协议才能进行通信。如:TCP、UDP、HTTP、FTP等等。
-
端口号
服务器的端口号就像是现实生活中的门牌号一样。通过门牌号,外卖员就可以准确把外卖送到你的手中。同样的道理,在一台电脑中,可以运行N多个web 服务。每个 web 服务都对应一个唯一的端口号(0-65535,2^16,常见的端口号别占用:20,21,22,25,80,443,3306,3389,11211,27017....)。客户端发送过来的网络请求,通过端口号,可以被准确地交给对应的 web 服务进行处理。0-65535
注:服务器上的端口号是不可以重复的,必须是独一无二。http服务默认端口号为80,https的端口号默认是443。
扩展:计算机的位数,32位(2^32)和64(2^64)位。计算机中的位数指的是CPU一次能处理的最大位数。
3.6.4、创建web服务器
NodeJs是通过官方提供的http模块来创建 web服务器的模块。通过几行简单的代码,就能轻松的手写一个web服务,从而对外提供 web 服务。
// 导入http模块 const http = require('http') // 创建web服务对象实例 const server = http.createServer() // 绑定监听客户端请求事件request // on方法做事件监听 server.on('request', (request, response) => {}) // request: 接受客户端请求对象,它包含了与客户端相关的数据和属性 // request.url 客户端请求的uri地址 // request.method 客户端请求的方式 get或post // request.headers 客户端请求头信息(对象) // .... // response:服务器对客户端的响应对象 // 设置响应头信息 ,用于响应时有中文时乱码解决处理 // response.setHeader('content-type', 'text/html;charset=utf-8') // 设置状态码(常见的HTTP状态码有:200,404,301、302、304、403、401、405、500,502) // response.statusCode = 200(默认是200) // 向客户端发送响应数据,并结束本次请求的处理过程 // response.end('hello world') // 启动服务 server.listen(8080, () => { console.log('服务已启动') })
案例:手写一个服务器软件,启动后要求用户访问根“/”输出hello world
,用户访问/html5
输出hello h5
。
// 1. 导入http模块 const http = require("http"); // 2. 创建web服务实例 const server = http.createServer(); // 3. 监听request请求 server.on("request", (req, res) => { // 输出hello world // res.end("hello world"); if (req.url === "/") { res.end("hello world"); } if (req.url === "/html5") { res.end("hello h5"); } }); // 4. 启动服务 server.listen(8080, () => { // 仅是提示作用,可以不写,但是建议写 console.log("server is running at http://127.0.0.1:8080"); });
3.5.5、静态资源服务器
静态资源:常见的有html、css、js、图片、音频、视频等
静态资源服务器:专门保存上述静态资源的服务器,称之为静态资源服务器。
-
实现思路
客户端请求的每个资源uri地址,作为在本机服务器指定目录中的文件。通过相关模块进行读取文件中数据进行响应给客户端,从而实现静态服务器。
-
实现步骤
需求:使用nodejs的http模块创建静态资源服务器,专门存放静态资源展示2张图片
// 创建服务器有以下几步: // a. 导入 const http = require("http"); const path = require("path"); const fs = require("fs"); // b. 创建web实例 const server = http.createServer(); // c. 监听request事件 server.on("request", (req, res) => { // 获取当前用户访问的资源路径 let uri = req.url; // 由于“/”没有实体资源,需要将“/”做处理,如果访问“/”则让其对应访问“/index.html” if (uri == "/") { uri = "/index.html"; } // 默认情况下,浏览器在第一次请求网站的时候会访问“/favicon.ico”图标文件,如果没有也会出现404 // 如果需要解决这个问题,则有3种方式: // 方式1:去找个ico文件,存放在静态资源的public目录下,命名为“favicon.ico” // 方式2:在处理的时候忽略“/favicon.ico”文件的处理,也就是下面的加了判断的写法 // 方式3:不管,不用处理,其不影响页面的显示 if(uri != '/favicon.ico'){ // 读取文件(fs模块),将内容返回给用户(res.end) let filename = path.join("public", uri); // 判断文件是否存在 if (fs.existsSync(filename)) { fs.readFile(filename, (err, data) => { if (!err) { // ok res.end(data); } else { // 不ok res.setHeader("Content-Type", "text/html;charset=utf-8"); res.statusCode = 500; res.end("请求资源出现错误。。。"); } }); } else { res.setHeader("Content-Type", "text/html;charset=utf-8"); res.statusCode = 404; res.end("你要找的资源失踪了。。。"); } } }); // d. 监听端口,启动服务 server.listen(8080, () => { console.log("server is running at http://127.0.0.1:8080"); });
==作业:实现自己的静态资源服务器,将todolist案例放入静态资源文件夹,确保代码能够正常运行==
3.6.6、get数据获取
get数据通过地址栏使用query方式进行传递的数据 例?id=1&name=zhangsan
// 导入 const http = require('http'); const url = require('url'); // 创建实例&监听request事件&监听端口 http.createServer((req, res) => { // 之前第3步中的回调函数 // 获取地址栏中 query数据 let { query } = url.parse(req.url, true); console.log(query); }).listen(8080)
3.6.7、post数据获取
表单数据多数为post进行提交到服务器端。需要监听req对象的data事件(接收请求提交过来的数据的)来获取客户端发送到服务器的数据。如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后分批次发送给服务器。所以data事件==可能==会被触发多次,每次触发data事件时,收到的数据只是全部数据的一部分,因此需要做数据的拼接才能得到完整的数据:
const http = require('http'); const queryString = require('querystring'); http.createServer((req, res) => { let arr = []; // 数据接受中 req.on('data', buffer => { arr.push(buffer); }); // 数据传输结束了 req.on('end', () => { // 拼接接受到的所有数据 let buffer = Buffer.concat(arr); let post = queryString.parse(buffer.toString()) console.log(post); }); }).listen(8080)