Node.js基础教学(三)

九、HTTP模块

1、基本概念

1.1 交互模式

B/S:指基于 浏览器(Browser) 和 服务器(Server) 这种交互形式

C/S:指基于 客户端(Client) 和 服务器(Server) 这种交互形式

1.2 终端的概念:

服务器:在网络节点中,专门对外提供资源服务的机器;

客户端:在网络节点中,专门用来消费服务的一台电脑;

1.3 静态资源与动态资源:

静态资源:服务器端只需要读取并直接发送给客户端、不需要进一步处理的资源。

动态资源:服务器端没有现成的资源,需要服务器端动态生成的资源。

2、Web应用架构

Client - 客户端,一般指浏览器,浏览器可以通过 HTTP 协议向服务器请求数据。

Server - 服务端,一般指 Web 服务器,可以接收客户端请求,并向客户端发送响应数据。

Business - 业务层, 通过 Web 服务器处理应用程序,如与数据库交互,逻辑运算,调用外部程序等。

Data - 数据层,一般由数据库组成。

3、http协议通信模型

数据流形式:请求 -> 处理 -> 响应

请求:由客户端发起请求;

处理:由服务器端处理请求;

响应:服务器端把处理的结果,通过网络发送给客户端

HTTP 协议会话过程的 4 个步骤

●建立连接:客户端的浏览器向服务端发出建立连接的请求,服务端给出响应就可以建立连接了。

●发送请求:客户端按照协议的要求通过连接向服务端发送自己的请求。

●给出响应:服务端按照客户端的要求给出应答,把结果(HTML 文件)返回给客户端。

●关闭连接:客户端接到应答后关闭连接

4、URL组成

URL是统一资源定位符,一种特殊类型的URI,根据一个 url 能够在全球确定一个唯一的资源,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

4.1 组成

协议://子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值

4.2 http协议简介

HTTP(Hyper Text Transfer Protocol)< 超文本传输协议> 的缩写

http与https的区别

相同点:http协议和https,都是超文本传输协议,

不相同点:

1)http的参数信息是明文传输,而https的参数信息是加密传输,

2)https则是具有安全性的ssl加密传输协议。

3)端口号不同http是80,https是443

http请求信息的组成

● 请求方法URI协议/版本

● 请求头(Request Header)

● 请求正文

http响应信息的组成

●状态行:

●消息报头:响应报头后述

●响应正文:服务器返回的资源内容

常见的状态码
200 OK	// 客户端请求成功
301 Moved Permanently  //永久重定向
304 Not Modified    //请求资源未发生改变
307 Temporary Redirect    //临时重定向
400 Bad Request	// 客户端请求有语法错误,不能被服务器所理解
401 Unauthorized // 请求未经授权,这个状态代码必须和WWW-Authenticate 报头域一起使用
403 Forbidden	// 无权限访问,服务器收到请求,但是拒绝提供服务
404 Not Found	// 请求资源不存在,eg:输入了错误的 URL
500 Internal Server Error // 服务器发生不可预期的错误
502 Bad Gateway  //请求超时
503 Server Unavailable	// 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

5、Path模块

path模块,做路径的规范(拼接、获取某一部分,获取绝对路径/相对路径)

引入方式:
const path=require("path");
常用方法
1、path.basename(path[, ext])

获取当前路径参数的最后一部(即文件名字/文件夹的名字),以“/”为截取目标

参数

path,操作路径(绝对路径/相对路径)

ext,截取内容,此内容是被忽略掉,注:截取是从右向左一一匹配。匹配不上截取失败。

console.log(__filename);
console.log(path.basename(__filename));//03_Path模块.js
console.log(path.basename(__dirname));//1.29
console.log(path.basename("/a/b/c/"));//c
console.log(path.basename(__filename,"s"));//03_Path模块.j
console.log(path.basename(__filename,"ss"));//03_Path模块.js
console.log(path.basename(__filename,"块.js"));//03_Path模块
2、path.delimiter

获取当前运行环境的结束符

windows的结束符是;

其它系统是 :

console.log(path.delimiter);
3、path.dirname(path)

获取当前目录的父级目录

console.log(path.dirname(__filename));//D:\Work space\project-node\1.29
console.log(path.dirname("./a/b/c"));
4、path.extname(path)

获取文件路径的后缀名

注:它是以最后一个“.”作为截取,截取后面的部分

console.log(path.extname("./a/a/b"));//空
console.log(path.extname(__filename));//.js
console.log(path.extname(__dirname));//.29(特例)
console.log(path.extname("./a/b/c/d/e.f.g"));//.g(特例)
console.log(path.extname("./a/b/c/d/e.f."));//.(特例)
5、path.isAbsolute(path)

判断当前路径是否是绝对路径,返回值是布尔类型

注:此方法是以"/"为判断依据,如果是“/”开始责备视为绝对路径

console.log(path.isAbsolute(__dirname));//true
console.log(path.isAbsolute("/a/v/c/x"));//true
console.log(path.isAbsolute("D:/a/v/c/x"));//true
console.log(path.isAbsolute("//a/b/c/d"));//true
console.log(path.isAbsolute("./a/v/c/x"));//false
console.log(path.isAbsolute("../a/v/c/x"));//false
console.log(path.isAbsolute("D/a/v/c/x"));//false
6、path.join([…paths])

路径的拼接,返回值是一个路经字符串形式

参数路劲与参数路径采用,隔开,可以不使用"/"

注,路径的拼接支持"…/","./",会将其转义

console.log(path.join("a","b"));// a\b
console.log(path.join(__dirname,"b"));//D:\Work space\project-node\12.26\b
console.log(path.join(__dirname,"1.js"));//D:\Work space\project-node\1.29\1.js
console.log(path.join(__dirname,"../../../a/b/index.html"));//D:\a\b\index.html
console.log(path.join(__dirname,__dirname,"a","b"));
console.log(path.join(__dirname,"aa","1.js"));//D:\Work space\project-node\1.29\aa\1.js
console.log(path.join(__dirname,__filename));//D:\Work space\project-node\1.29\D:\Work space\project-node\1.29\03_Path模块.js
7、path.normalize(path)

规范化路径

注:此方法只支持 "./"的路径规范。

console.log(path.normalize(__filename));//绝对路径没有任何效果
console.log(path.normalize("./a/b/c/s"));//以"."开始的相对路径,此方法可以将"./"省略。
console.log(path.normalize("../a/b/d/c"));//以"../"开始的相对路径,此方法只会将"/"转换为"\"
console.log(path.normalize("ff/ee/../../a/b/c/d"));//a\b\c\d
console.log(path.normalize("/a/b/c/d/e"));//    \a\b\c\d\e
console.log(path.normalize("//a/b/c/d"));// \\a\b\c\d
8、path.parse(path)

将路径参数转换为对象,对象中包含(盘符,父级路径、文件名全名,后缀名、文件名)

console.log(path.parse(__filename));

6、URL模块

url模块推荐使用 WHATWG 标准的新API。

组成:

协议://子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标识

URL对象:返回一个URL对象,对象中包含(源地址、主机地址,协议,域名+端口,域名,端口号,资源路由,参数字符串,参数对象,标识符)

**注:**参数字符串会默认将中文字符进行编码操作

语法:
new URL(input[, base]);

input:要解析的绝对或相对的 URL。,注:如果input为绝对url,则不需要base属性,否则需要

base:主机地址

**注:**使用URL模块不需要引入,直接创建实例就可以生成URL对象

let urlstr=`https://www.baidu.com:1234/a/b/c/index.html?username=rypy&pwd=123456#aaa`;
let urlObj=new URL(urlstr);//创建一个URL实例,会将url类型的字符串转换为URL对象类型。
console.log(urlObj);
console.log(urlObj.origin);
console.log(urlObj.protocol);
console.log(urlObj.pathname);
注:searchParams类型的存储形式是Map数据结构。
console.log(urlObj.searchParams.get("username"));
let urlstr=`/a/b/c/index.js`;//目录(路由/资源路由)
//如果url字符串是相对URL不是绝对URL,则new实例的时候需要第二个参数,设置一个虚拟的服务器地址。
let urlObj=new URL(urlstr,`http://abc.abc.abc:1234`);
console.log(urlObj);

7、Querystring模块

querystring模块,用来解析和格式化url携带的参数。

1、引用.parse(str[, sep[, eq[, options]]])

将字符串类型的URL序列参数(浏览器地址栏的参数形式),转换为Object类型的对象,自带中文解码操作,可以将中文字符由原来的编码解析为中文汉字。

参数

str URL格式的字符串参数序列

sep,设置将URL字符串分割为对象的键值对的标志,默认值是"&"

eq,设置生成对象的键名与键值的分割标志,默认值是“=”

let urlstr=`username=rypy&pwd=123456`;
console.log(qs.parse(urlstr));//[Object: null prototype] { username: 'rypy', pwd: '123456' }
console.log(qs.parse(urlstr,"="));//[Object: null prototype] { '123456': '', username: '', 'rypy&pwd': '' }
let urlstr=`username:"我是web"|pwd:123456`;
console.log(qs.parse(urlstr,"|",":"));
2、引用.stringify(obj[, sep[, eq[, options]]])

将Object类型的对象转换为URL格式的参数序列字符串。自带编码功能,可以将中文字符转换为十六进制的值。

参数

obj 需要转换的对象

sep,设置拼接字符串的键值对的符号 默认值是“&”

eq,设置拼接字符串的键名与键值的符号 默认值是“=”

let user={username:"我是web",pwd:123456};
console.log(qs.stringify(user));
let urlstr=qs.stringify(user);
console.log(qs.parse(urlstr));
3、引用.escape(str)

将中文字符进行编码操作

let str=`我是web学生`;
console.log(qs.escape(str));
4、引用.unescape(str)

将编码后的中文字符进行解码操作

let str=`我是web学生`;
let str2=qs.escape(str);
console.log(qs.unescape(str2));

8、http原生创建启动服务代码

使用http模块 创建服务基本步骤3步

//1、引入http模块
const http=require("http");
//2、创建http实例
//创建实例采用createServer(callback)
//回调函数中含有两个形参,req,代表请求对象(request),res代表响应对象(response)
//request请求对象,用来获取请求相关信息的,请求携带的参数,请求头部的信息等。
//response响应对象,用来给客户端发送响应信息,响应头部,响应内容等
const server= http.createServer((req,res)=>{});
//3、设置端口号 (1~65398)
采用listen()方法
//参数一,端口号,
//参数二,局域网IP地址(本地TCP/IP地址),可以省略,省略的情况下域名为localhost,IP地址为127.0.0.1。
参数三,回调函数,可以省略,功能,启动服务的时候,服务器正常启动,可执行此回调函数。
server.listen(1234,"10.10.89.85",()=>{
    console.log("服务器已启动,IP地址是10.10.89.85,端口号1234");
});

9、http原生响应内容到浏览器

const http=require("http");
const server=http.createServer((req,res)=>{
    //在node原生http模块中,如果只响应一个首页路由,可以直接书写响应内容。
    //当需要给浏览器返回中文汉字的时候,必须要设置响应头部的编码格式。
    //设置响应头部,采用的方法writeHead()
    //writeHead() 参数1,设置响应状态码 ,参数2,设置状态的码的消息(可省略,但是不能是中文),参数3 对象的形式,设置 Content-Type属性的值,其值可以设置资源文件的类型。
    //res.writeHead(400,"this is a big error!",{"Content-Type":"text/html;charset=utf8;"});//设置响应html文件的MIME类型。
    res.writeHead(400,"this is a big error!",{"Content-Type":"text/plain;charset=utf8;"});//设置响应html文件的MIME类型。
    //MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,又称文档类型。功能:告知浏览器,当前响应的文件类型,
    //res.write(),向浏览器端响应输出内容。//注:write()可以与write()方法本身和end(),同时返回响应内容,而且是可以做拼接操作。
    res.write("我是write第一个方法响应的内容");
    res.write("我是write第二个方法响应的内容");
     //res.end();//结束响应并向浏览器端传送,参数内容,且参数内容可以响应到浏览器内容区。
    res.end(`<h1 style="color:red">hello node!</h1>我检查口罩!`);
    //注:end方法必须要放置在响应内容的最后面。否则会报错。
    //注:如果修改了服务器端代码,必须重新启动服务。
});
server.listen(1234);
//注:如果在启动的时候出现 address already in use 10.10.89.85:1234,就代表域名和端口号重复,目前有该域名和端口号的服务启动,出现错误的解决办法:修改域名/IP,或者修改端口号。
//命令行终止node启动的服务 ctrl+c

10、http模块响应资源文件

MIME类型,是多用途互联网邮件扩展类型,又称文档类型,功能告诉浏览器,我当前服务器传递的资源是什么类型,不同的类型,浏览器会做不同的响应。

常见的MIME类型(通用型):

名称文件格式MIME类型
超文本标记语言文本.htmltext/html
xml文档.xmltext/xml
XHTML文档.xhtmlapplication/xhtml+xml
普通文本.txttext/plain
RTF文本.rtfapplication/rtf
PDF文档.pdfapplication/pdf
PNG图像.pngimage/png
Microsoft Word文件.wordapplication/msword
GIF图形.gifimage/gif
JPEG图形.jpeg,.jpgimage/jpeg
css文件.csstext/css
Json文件.jsonapplication/json
JS文件.jstext/JavaScript
const http=require("http");
const fs=require("fs");
const path=require("path");
http.createServer(async (req,res)=>{
    let [err,data] =await new Promise(resolve=>{
fs.readFile(path.join(__dirname,"./css/index.css"),"utf8",(err,data)=>{
            // if(err)resolve(err);
            // else resolve(data);
            resolve([err,data]);
        });
    });
    if(err){
        res.writeHead(200,"ok",{"Content-type":"text/html;charset=utf8;"});
    }else{
        res.writeHead(200,"ok",{"Content-type":"text/css"});
        res.end(data);
    }
}).listen(520);

11、http响应静态资源

const http=require("http");
const path=require("path");
const fs=require("fs");
http.createServer(async (req,res)=>{
    //req.url,获取 资源路由和参数,返回值是一个字符串
    let [urlPath,params]=req.url.split("?");//将资源路由和参数,进行分割
    console.log(params);
    let htmlText="";//此变量用来接收读取文件的内容
    switch(urlPath){
        //注:在服务器端定义路由一定要带"/",如"/index.css",
        //注:"/",通常被称作 主路由
        case "/index.css":
            res.writeHead(200,"ok",{"Content-type":"text/css"});
            htmlText=await getFileData("css/index.css");
        break;
        case "/jquery.min.js":
            res.writeHead(200,"ok",{"Content-type":"text/javascript"});
            htmlText=await getFileData("js/jquery.min.js");break;
        case "/index.html":
            res.writeHead(200,"ok",{"Content-type":"text/html"});    
            htmlText=await getFileData("html/index.html");break;
    }
    if(htmlText[0]){
        res.end(htmlText[0]);
    }else{
        res.end(htmlText[1]);
    }
}).listen(1111,"10.10.10.166");
//读取静态资源文件
function getFileData(filepath) {
    return new Promise(resolve=>{  fs.readFile(path.join(__dirname,"public",filepath),"utf8",(err,data)=>{
            resolve([err,data]);
        });
    });
}

12、http模参数的获取

http模块获取get请求参数

**req.url:**获取资源路由和参数

"/":一般再服务器端称之为主路由,一般用来响应首页

如果不设置服务器端IP地址,则使用localhost或127.0.0.1

const http=require("http");
const qs=require("querystring");
const {getFilePage}=require("./model/fileControl");
http.createServer(async (req,res)=>{
    let err="";
    let htmlText="";
    let htmlType="";
    let [urlPath,params]=req.url.split("?");
    switch(urlPath){
        /*      静态资源部署区域    */
        case "/":; 
        case "/index.html":
            htmlType="text/html";
            [err,htmlText]= await getFilePage("index.html");
            break;
        case "/jquery.min.js":
           htmlType="text/javascript";
            [err,htmlText] = await getFilePage("./js/jquery.min.js");
            break;
        case "/index.js":
           htmlType="text/javascript";
            [err,htmlText]= await getFilePage("./js/index.js");
            break;
        /*   动态资源获取区域   */    
        case "/reguest":
          htmlType="application/json";
          let user=qs.parse(params);//将url参数类型的对象转换为真正对象
          	if(user.username==="admin"&&user.pwd==="123456"){ 
            	htmlText=JSON.stringify({msg:"登录成功"});
            }else{
                htmlText=JSON.stringify({msg:"登录失败"});
            }        
    }
    if(err){
        htmlType="text/html";
        htmlText="服务器端出现错误!";
    }
    res.writeHead(200,"ok",{"Content-Type":htmlType});
    res.end(htmlText);//只能以字符串的形式返回JSON格式的数据。
}).listen(2222,"10.10.10.166");
http模块获取post请求参数

在http原生种如果需要响应post请求并获取参数,需要做事件监听。

**注:**如果监听了data事件就必须监听end事件。且如果监听了end事件,响应的end方法必须写在请求的end事件中,那么当监听了end事件以后,由于请求事件的监听是用同一个请求,所以data事件种回调函数的参数值,可以在end种使用。

req.on("data",(data)=>{});
req.on("end",async ()=>{//end事件中,完成路由的响应
//注:如果监听了end事件,响应的end方法必须写在请求的end事件中
        res.end(htmlText);
});

十、服务器简介

常见服务器包括Apache、Apache Tomcat、IIS、Node、Nginx、WebLogic、kangle等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值