nodejs day02 package.json文件 服务端开发

nodejs-day02

1.package.json文件

package.json文件就是一个项目信息描述的文件,它用来记录项目的一些基本信息,还有第三方模块的记录信息。

如果我们需要自己创建一个全新的项目,也需要创建项目的描述文件package.json
在项目文件夹下打开终端,执行命令 npm init -y 就可以生成一个 package.json 文件,文件内容描述如下:

{
  "name": "demo", //项目名称
  "version": "1.0.0", //项目版本
  "description": "",  //项目描述
  "main": "index.js",  //项目的入口文件
  "scripts": {  //项目的脚本
  "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [], //关键字
  "author": "", //作者
  "license": "ISC" //开发协议
  "dependencies": {  //项目的运行依赖 :代表项目运行的时候需要使用到的第三方包。
    "jquery": "^3.4.1"
  },
  "devDependencies": {  //项目的开发依赖:项目开发阶段需要用到的第三方包
      "less":"2.5"
  }
}

注意:

package-lock.json文件 会记录下载第三方包的源地址。
如果项目出了问题,第三方包需要重新下载,我们使用npm install命令下载的时候就会直接找到package-lock.json文件中记录的地址直接下载。

2. 服务器

服务器:能够提供web访问服务的机器就是网站服务器,能接收浏览器端的请求,能对请求做出响应。

客户端:就是使用服务的电脑,或者浏览器

ip地址:就是一串数字,使用这一串数字来区分 internet 上的每一台电脑 本机有一个特定的 IP 地址是127.0.0.1;每一个电脑使用的ip地址是不能重复的,就像身份证编号一样,是不能重复的。
ip地址是由4个0~255的数字组成,比如说:192.168.14.102

域名:ip地址难以记忆,有含义的域名是比较好记忆的,我们访问网站的时候不会使用ip地址去进行访问
而是使用域名。域名和ip地址之间是有对应关系的。如果将本机作为服务器,本机有一个特定的域名是 localhost

端口:指的是服务器上提供服务的地方,在一台电脑中,端口范围0~65535。
每一个服务需要占用一个端口,我们可以根据不同的端口号去使用服务器不同的服务。
0~1024端口是系统使用的端口,最好不要去使用。

url地址:http://localhost:8080/#/login

http:// :协议 我们访问网站的时候是要遵循http协议的 。

localhost :访问的网站的域名,localhost代表的是我们自己的电脑。

:8080 :网站使用了8080端口提供服务

http://www.itcast.cn:8080/first/index.html?uname=jack&pwd=123#one
/first/index.html :访问服务器中的文件的路径
?uname=jack&pwd=123 : url地址参数
#one :锚链接

3. 服务器与客户端间的请求与响应

创建web服务器
在NodeJs中不需要安装额外的软件充当网站服务器,NodeJs中提供的HTTP模块即可创建web服务器。

// 引用系统模块
const http = require('http');
// 创建web服务器
const server = http.createServer();
// 当客户端发送请求的时候
server.on('request', (req, res) => {
// 设置响应头    
res.writeHead(200, {    
'Content‐Type': 'text/html;charset=utf8'        
});    
// 设置响应体    
res.write('<h1>哈哈哈</h1>');    
// 结束请求    
res.end();    
});
// 监听3000端口
server.listen(3000, error => {
    if (!error) {
     console.log('服务器已启动,监听3000端口,请访问 localhost:3000')        
    }
});

浏览器向服务器发送的叫做请求( request )

服务器向浏览器返回的结果叫做响应( response )

在发送请求的时候,最重要的就是要知道请求的地址是什么,还有请求的方式是什么

请求分为get,post两种方式,参数被放置在地址栏中,格式为:name=zhangsan&age=20

get方式一般用来获取数据

// 处理get参数
const url = require('url');
let { query } = url.parse(req.url, true);

post方式一般用来发送数据

// 处理post参数
// 由于post传递的参数数据量比较大,在网络中并不是一次性传递完成的,而是分成了多次传递
// 所以在接收的时候也需要分为多次接收
// 在NodeJs中接收post参数需要使用事件完成
const querystring = require('querystring');
let formData = '';
req.on('data', chunk => formData += chunk);
req.on('end', () => console.log(querystring.parse(formData)));
//on方法就是事件监听,监听的是request事件,request事件会在客户端访问服务器的时候发生

app.on("request",function(req,res){
//req这个参数表示的是request请求对象
//res这个参数表示的是response响应对象

req.method;// 获取浏览器向服务器发送的请求类型 (get/post);
req.url;// 获取浏览器访问服务器的对应地址 。
req.headers;// 获取浏览器发送给服务器的请求信息

res.end("hello world");
})

req.method;// 获取浏览器向服务器发送的请求类型 (get/post);

req.url;// 获取浏览器访问服务器的对应地址 。

req.headers;// 获取浏览器发送给服务器的请求信息

使用系统模块url来处理请求路径

导入url模块

const url = require(“url”);

使用url模块提供的parse方法来解析请求中的url地址,parse方法的第二个参数意思是 是否需要将参数解析为对象

const urlObj = url.parse( req.url, true );

使用解构赋值获取到urlObj对象中的属性

//const query = urlObj.query

//const pathname = urlObj.pathname

const { query, pathname } = urlObj

前端发送post请求,后台如何处理

前端需要使用form表单来发送post请求,如果表单中的表单元素有name属性,那么这个表单元素会作为post请求的参数数据进行发送

<form action="http://localhost:3000/post" method="post">
    <!-- zhanghao=jack&pass=123456 -->
    账号:<input type="text" name="zhanghao">
    密码:<input type="password" name="pass">
    <input type="submit">
</form>

后台要如何接收post请求的数据(请求参数),并进行处理

//需要使用querystring模块进行参数数据转换为对象的处理

const querystring = require('querystring');

//使用url模块进行解析

const urlObj = url.parse( req.url , true );

//解构赋值

const { query,pathname } = urlObj;

if(pathname == '/' || pathname=='/index'){

    res.writeHead(200,{
        "content-type":"text/html;charset=utf8"
    })
    res.end("<h1>下午好,"+query.uname+"</h1>");

}else if(pathname=='/post' && req.method == 'post'){

    var res = "";
    //要接收前端发送的参数数据,需要使用两个事件,data事件,end事件
    req.on("data",function(val){
        res+=val;
    })
    //如果触发了end事件,说明数据已经接收完毕了
    req.on("end",function(){
        const obj = querystring.parse( res );
    
        console.log(obj);
    
        res.end("处理post请求完毕");
    })

}else{

    res.writeHead(404,{
        "content-type":"text/html;charset=utf8"
    })
    res.end("<h1>您请求的资源不存在</h1>");

}

4. 路由

路由是指URL地址与程序的映射关系,更改URL地址可以改变程序的执行结果。简单说就是请求什么响应什么

const http = require('http');
const url = require('url');
const finalhandler = require('finalhandler')
// 创建网站服务器
const server = http.createServer();
// 当客户端发来请求的时候
server.on('request', (req, res) => {
// 处理404方法    
var done = finalhandler(req, res);    
// 获取客户端的请求路径    
let { pathname } = url.parse(req.url);    
// 对请求路径进行判断 不同的路径地址响应不同的内容    
if (pathname == '/' || pathname == '/index') {    
res.end('index');        
}else if (pathname == '/list') {    
res.end('list');        
}else if (pathname == '/about') {    
res.end('about');        
}else {    
        // 如果以上路由都没有匹配上, 则进行404处理
done();        
}    
});
// 程序监听端口
server.listen(3000);

5. 静态资源访问

1.获取客户端要访问的那个地址中的文件的路径
//假如url获取的是 /index.html /list.html /1.jpg
let url = url.parse(req.url).pathname;
2.将获取的url路径进行拼接变成服务器的绝对路径
let filepath = path.join(__dirname,“public”,url);
3.可以使用fs模块去读取文件

在读取文件之前应该要先获取文件的mime类型。

// 在终端中执行命令 npm i mime 下载 mime 模块

const mime = require("mime");

const type = mime.getType(filepath);

fs.readFile(filepath,function(err ,doc){

    if(!err){
        res.writeHead(500,{
            "content-type":"text/html";
        })
        res.end("<h1 >服务器读取网页失败</h1>");
        return;
    }
    
    //需要设置mime类型
    res.writeHead(200,{
        "content-type": type;
    })
    
    //将读取到的文件源代码返回给客户端
    res.end(doc);

})

6. nodejs工作原理

同步异步
同步或者异步指的是服务器端处理请求的方式。
同步方式
生动形象的比喻

当你来到餐馆,一个指定的服务员被分配给你服务,当你点完餐时,服务员将订单送到厨房并在厨房等待厨师制作菜肴,
当厨师将菜肴烹饪完成后,将菜肴送到你的面前,服务完成.此时这个服务员才能服务另外的客人.同步模式就是一个服 务员同时只能服务于一个客人.
你可以想象,餐馆就是服务器,服务员就是线程,客户端向服务器端发送的请求就是吃饭的客人.当客户端向服务器发送
请求时,服务器端需要为请求分配一个线程处理该请求,在请求的过程中可能会去读取出数据或者文件,这是一个需要
时间的操作,就好像厨师炒菜需要时间一样,此时线程只是等待操作的完成.如果此时有新的请求来了,服务器需要分配
一个新的线程为该请求服务,必须要知道的是,分配一个线程大约消耗服务器端2MB的内存.想象一下,如果同一时间,
服务器接收到大量的请求,服务器可能会消耗掉所有内存提供服务,同一时间再有请求来的时候必须等待,等待有空闲
的线程才能为该请求服务,如果不想让该请求等待,服务器端需要增加更多的硬件(内存)设备.这种同步方式显然没有 有效的利用现有的资源.

异步方式
生动形象的比喻

当你来到餐馆,在点餐后服务员将你的订单送到厨房,此时服务员没有在厨房等待厨师烹饪菜肴,而是去服务了其他客人,当厨房你的菜肴烹饪好以后,服务员再将菜肴送到你的面前.异步模式就是一个服务员同时可以服务多个客人.
Node就是基于异步的应用程序.在Node中,用一个线程处理所有的请求.当客户端向服务器端发送请求时,服务器端的一个线程处理该请求,在请求的过程中如果去查询数据库或者读取文件,该线程不会等待查询的结果,转而去处理其他请求,Node程序会监控数据库的查询结果,如果查询完成,该线程会重新回来处理该请求.Node擅长处理高并发的网络请求或频繁的数据取读取型应用程序,不会带来硬件成本的增加.这种异步的模式显然有效的利用了现有的资源.

代码执行顺序
同步方式

代码一行一行执行,下一行的代码必须等待上一行代码执行完成以后才能执行.

异步方式

他可以同时运行多句代码,效率会更高。

Promise
Promise出现的目的是解决Node.js异步编程中回调地狱的问题
Promise本身是一个构造函数,要使用promise解决回调地狱的问题 需要使用new运算符创建Promise构造函数的实例对象
在创建对象的时候需要传入一个匿名函数,匿名函数中有两个参数 resolve,reject
这个方式其实还可以优化
异步函数
异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了
async 关键字
作用:

  1. 普通函数定义前加async关键字 普通函数变成异步函数
  2. 异步函数默认返回promise对象
  3. 在异步函数内部使用return关键字进行结果返回 结果会被包裹的promise对象中 return关键字代替了promise中的resolve方法
  4. 在异步函数内部使用throw关键字抛出程序异常
  5. 调用异步函数再链式调用then方法获取异步函数执行结果
  6. 调用异步函数再链式调用catch方法获取异步函数执行的错误信息

await关键字

  1. await关键字只能出现在异步函数中
  2. await promise await后面只能写promise对象 写其他类型的API是不不可以的
  3. await关键字可是暂停异步函数向下执行直到promise返回结果
//使用 promisify 改造函数
//promisify的作用就是将函数转换成promise对象
//const promisify = require("util").promisify;
//const fn = promisify(需要转换的函数名);

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        if (true) {
            resolve({name: '张三'})
        }else {
            reject('失败了')
        }
    }, 2000);
});
promise.then(result => console.log(result); // {name: '张三'})
       .catch(error => console.log(error); // 失败了)
const fn = async () => {};
async function fn () {}
// 改造现有异步函数api 让其返回promise对象 从而支持异步函数语法
const promisify = require('util').promisify;
// 调用promisify方法改造现有异步API 让其返回promise对象
const readFile = promisify(fs.readFile);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值