Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erklärung von Express in NodeJS

Detaillierte Erklärung von Express in NodeJS

青灯夜游
青灯夜游nach vorne
2021-03-11 10:09:252695Durchsuche

Dieser Artikel stellt Ihnen Express in node vor. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.

? json Das Feld „Start“ wird wie folgt geändert:

npm install nodemon -D
Detaillierte Erklärung von Express in NodeJS Aber jetzt finden wir ein Problem: Egal welche Änderungen an einer Datei vorgenommen werden, der Knoten wird neu gestartet.

Wir spezifizieren einfach: JS-Dateien überwachen:

Neue nodemon.json erstellen

"start":"nodemon js路径+名",
//增加一行
"start:node":"node js路径+名",
...

(src ist der Verzeichnisname auf der gleichen Ebene wie json (wo sich js befindet))

Danach kann der Server automatisch npm start.

Zurück zum Geschäft, Express ergreift Maßnahmen

Unser erstes Wissen über Express: ein Web-Framework in Node.

Wie folgt: Verwenden Sie Express, um eine Webanwendung zu erstellen

{
	"watch":["./src/**/*.js"]
}

Setzen Sie app.js im src-Verzeichnis (selbst erstellter Ordner) ein:npm start了。

言归正传,Express出手

我们对express的第一认知:node中的一种web框架。

如下:用express搭建一个web应用

npm install express -S       # "-S":在生产环境中搭载
npm install nodemon -D

在src目录(自建文件夹)下设app.js:

const express=require('express');
//一个express实例
const app=express();
//app.use((req,res)=>{
//	res.json({
//	name:"张上"
//	})
//})
app.get('/name',(req,res)=>{
	let {age}=req.params;
	res.send('tom');
});
app.post('/name',(req,res)=>{
	res.send('tom post');
});

app.listen(8081,()=>{
	console.log('启动成功');
});

看到代码第3行,有没有想到http?
const server=http.createServer((req,res)=>{...});
这里的server和上面的app是一样的。但是两个req不一样,因为app的req是经过express封装过的,它的功能更丰富!

在package.json(生成的配置文件)中修改:

// "script"选项下第一个——"start"值中加一个“nodemon”字样:
"start":"nodemon ./src/app.js",
...

那如上代码怎么传参?

// get方式传参
app.get('/name/:age',(req,res)=>{
	let {age}=req.params;
	res.json({
		name:'tom',
		age
	})
})

Router的介绍 & 使用

web服务如何处理一个请求
url --> 网络 --> dns解析 --> 目标服务器

  • 如何响应这个请求 —— 路由!(规则)

  • 如何区分 —— 请求方法(get/post)、uri(路径)

const express=require('express');
const app=express();
//1.请求方法判断 ——测试工具:postman
app.get('/demo',(req,res)=>{
	res.json({
		message:'hello get mxc'
	})
});
app.post('/demo',(req,res)=>{
	res.json({
		message:'hello post mxc'
	})
});

//2.通过URI ——postman上测试:http://127.0.0.1:8081/user/byname?name=mxc
//或:http://127.0.0.1:8081/user/byid?id=123
app.get('/user/byname',(req,res)=>{
	let {name}=req.query;
	res.json({
		name
	})
});
app.get('/user/byid',(req,res)=>{
	let {id}=req.query;
	res.json({
		id
	})
});

app.listen(8081,()=>{
	console.log('server已启动');
});

路由API

定义一个api,需要满足 客户端 无论以什么请求方式,都可以得到响应

app.all('/demo',(req,res)=>{
	res.json({
		message:'demo',
		method:req.method
	})
});

无论客户端使用任何URI,我们的服务都可以响应(日志)

app.all('*',(req,res)=>{
	res.json({
		message:'demo',
		method:req.method,
		uri:req.path
	})
});

app.use --> 中间件

app.use('/demo',(req,res)=>{
	res.json({
		message:'from use demo',
		method:req.method
	})
});

app.use((req,res)=>{
	res.json({
		message:'demo',
		method:req.method,
		uri:req.path
	})
});

如何做路由的拆分? —— express.Router

在member.router.js文件中:

const express=require('express');
const router=express.Router();
//router.[method]//(get/post)
//router.all
//router.use
router.get('/list',(req,res)=>{
	res.json({
		list:[
			id:001,
			name:'mxc'
		]
	})
});
module.exports=router;

在app.js中“ 注册路由 ”:

const memberRouter=require('./member.router.js');app.use(memberRouter);

现在我们再写一个skuRouter的路由,它的URI中也有“/list”。
注册完以后。我们发现找不到了(打印不出来),那这怎么办?

其实,路由use里面我们可以加一个“前缀”——也就是“根”,加以区分:

const memberRouter=require('./member.router.js');
app.use(memberRouter);

中间件

express中间件

使用:

  • app级别使用(注册时,一定是在最顶级/端)

  • router级别

  • 异常处理

(普通)中间件

我们应当先考虑一个问题:为什么需要“中间件”:程序不能一步“走完”。

你比如说下面这个demo:获取input内容:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action="http://localhost:8081" method="post">
用户:<input type="text" name="user" /><br />
密码:<input type="password" name="pass" /><br />
<input type="submit" value="提交">
</form>
</body>
</html>
npm install body-parser
const express=require('express');
const bodyParser=require('body-parser');
var server=express();
server.listen(8081);
server.use(bodyParser,urlencoded({}));
// 上面一行有时也写为:server.use(bodyParser,urlencoded({extended:true}));
server.use('/',function(req,res){
	console.log(req.body);
});

毫无疑问,这比平时“多出来的”一行:server.use(bodyParser,urlencoded({})); 就是所谓的“中间件的使用”。

现在该思考另一个问题了:为什么程序“一步走不完”?
如上述代码, POST的req中应该有“ body ”吗?
很显然不应该。 body本来就不存在啊!(不然ajax还去用data?)

但我们现在确实需要。所以第2行const bodyParser=require('body-parser'); 申请了“中间件模块”,在第5行为整个“链式操作”(两个use连着)给“装上”了一个body。

通常来说,在实战中中间件我们会写3个,构成一条“完整的”参数解析大法:
app.use(express.json());
app.use(express.urlencoded());
app.use(bodyParser,urlencoded({extended:true}));
//然后再get/post操作

当然,如果前面是GET方式提交,node中直接用req.query即可,也就不需要中间件了。

那既然中间件这么“有用”,不如自己封装一个?
mxc-body-parser.js文件

// 仿body-parser中间件
const querystring=require('querystring');
module.exports=function(req,res,next){
	var str='';
	req.on('data',function(data){
		str+=data;
	});
	req.on('end',function(){
		req.body=querystring.parser(str);
		next();
	});
}

然后在其他文件里引用:

const express=require('express');
const mxcParser=require('./lib/mxc-body-parser');
var server=express();
server.listen(8081);
server.use(mxcParser);
server.use('/',function(req,res){
	console.log(req.body);
});

异常处理

——可视化
通常,异常处理都是全局进行的。

一般做法:throw new Error('测试功能异常');

function error_handler_middleware(err,req,res,next){
	if(err){
		let {message}=err;
		res.status(500).json({
			message:`${message || '服务器异常'}`
		})
	}else{
		//其余操作
	}
}
...
app.use(error_handler_middleware);   //放在所有Router最后,做中间件用

Sehen Sie sich die dritte Zeile des Codes an. Haben Sie an http gedacht? const server=http.createServer((req,res)=>{...});

Der Server hier ist derselbe wie die App oben. Die beiden Anforderungen sind jedoch unterschiedlich, da die Anforderungen der App durch Express gekapselt sind und über umfangreichere Funktionen verfügen!

Ändern Sie in package.json (generierte Konfigurationsdatei):
npm install express mysql2 sequelize nodemon sequelize-cli -S

Wie werden Parameter im obigen Code übergeben?

"database":"数据库表名",
"timezone":"+08:00"

Router-Einführung und Verwendung des

🎜🎜Webdienstes zur Verarbeitung einer Anfrage🎜🎜 URL --> DNS-Auflösung --> Typ: Disc;">
  • 🎜So antworten Sie auf diese Anfrage - Routing! (Regeln)🎜
  • 🎜Wie unterscheidet man – Anforderungsmethode (get/post), uri (Pfad)🎜
  • npx sequelize db:migrate
    🎜🎜Routing-API🎜🎜🎜Definieren Sie eine API, Bedarf Stellen Sie den Kunden zufrieden, egal welche Anfragemethode wir erhalten. Egal welche URI der Kunde verwendet, unser Dienst kann antworten (protokollieren). Wie teilt man das Routing auf? 🎜 —— express.Router🎜🎜In der Datei member.router.js: 🎜
    use strict' ;
    module. exports = (sequelize, DataTypes) => {
    	const Todo = sequelize.define( 'Todo', {
    		name: DataTypes. STRING,
    		deadLine: DataTypes .DATE,
    		content: DataTypes. STRING
    	},{
    		timestamps:false
    	}) ;
    	Todo. associate = function(models) {
    		// associations can be def ined here
    	};	
    	return Todo;
    };
    🎜In app.js „🎜Register Route🎜“:🎜
    app.post('/create',async (req,res,next)=>{
    	try{
    		let {name,deadline,content}=req.body;
    		//持久化到数据库
    		let todo=await models.Todo.create({
    			name,
    			deadline,
    			content
    		})
    		res.json({
    			todo,
    			message:'任务创建成功'
    		})
    	}catch(err){
    		next(error)
    	}
    })
    🎜Jetzt schreiben wir eine weitere Route für skuRouter, und ihr URI hat auch „ /list ". 🎜 Nach Anmeldung. Wir stellen fest, dass wir es nicht finden können (es nicht ausdrucken können). Was sollen wir tun? 🎜🎜Tatsächlich können wir der Route ein „Präfix“ – also „root“ – hinzufügen, um sie zu unterscheiden: 🎜
    app.use((err,req,res,next)=>{
    	if(err){
    		res.status(500).json({
    			message:err.message
    		})
    	}
    })
    🎜🎜Middleware🎜🎜🎜🎜Express-Middleware🎜🎜🎜Verwendung: 🎜
    • 🎜Nutzung auf App-Ebene (bei der Registrierung muss sie sich auf der obersten Ebene/Ende befinden)🎜
    • 🎜Router-Ebene🎜
    • 🎜Ausnahmebehandlung 🎜
    🎜🎜 (gewöhnliche) Middleware 🎜🎜🎜 Wir sollten uns zunächst eine Frage stellen: Warum wird „Middleware“ benötigt: Das Programm kann nicht in einem Schritt „abgeschlossen“ werden. 🎜🎜Nehmen Sie zum Beispiel die folgende Demo: Holen Sie sich den Eingabeinhalt: 🎜rrreeerrreeerrreee🎜 Es ​​besteht kein Zweifel, dass dies eine „zusätzliche“ Zeile als üblich ist: server.use(bodyParser,urlencoded({})); Es handelt sich um den sogenannten „Einsatz von Middleware“. 🎜🎜Jetzt ist es an der Zeit, über eine weitere Frage nachzudenken: Warum kann das Programm nicht in einem Schritt abgeschlossen werden? 🎜 Sollte wie im obigen Code „body“ in der Anforderung von POST enthalten sein? 🎜 Offensichtlich sollte es nicht so sein. Der Körper existiert überhaupt nicht! (Sonst nutzen wir noch Daten für Ajax?) 🎜🎜Aber wir brauchen sie jetzt wirklich. Zeile 2 <code>const bodyParser=require('body-parser'); gilt also für das „Middleware-Modul“ und Zeile 5 gibt die gesamte „Kettenoperation“ (zwei verbundene Verwendungen) an „ Installierte einen Körper . 🎜
    🎜Im Allgemeinen werden wir im tatsächlichen Kampf drei Middlewares schreiben, um eine „vollständige“ Parameter-Parsing-Methode zu bilden: 🎜app.use(express.json());🎜 app.use(express.urlencoded());🎜app.use(bodyParser,urlencoded({extended:true}));🎜//Dann noch einmal get/post Operation🎜
    🎜Wenn sich die vorherige Übermittlung im GET-Modus befindet, verwenden Sie natürlich einfach req.query direkt im Knoten, sodass keine Middleware erforderlich ist. 🎜🎜Da Middleware so „nützlich“ ist, warum nicht selbst eine kapseln? 🎜🎜mxc-body-parser.js-Datei🎜🎜rrreee🎜Dann referenzieren Sie sie in anderen Dateien:🎜rrreee🎜🎜Ausnahmebehandlung🎜🎜🎜——Visualisierung🎜 Normalerweise erfolgt die Ausnahmebehandlung global. 🎜🎜Allgemeiner Ansatz: throw new Error('test function Exception');🎜 Node-Express integrierte Ausnahmebehandlung: 🎜rrreee🎜🎜ORM-Modellerstellung im tatsächlichen Kampf🎜🎜🎜🎜Lass uns darüber reden Zuerst die Datenbankinitialisierung 🎜🎜🎜Nachdem wir MySQL erstellt haben, müssen wir Knoten und MySQL verbinden. Die verwendeten Tools: 🎜
    npm install express mysql2 sequelize nodemon sequelize-cli -S

    连接成功后会生成config.json配置文件,我们在development选项中修改和添加:

    "database":"数据库表名",
    "timezone":"+08:00"

    持久化模型对应的数据库表:

    npx sequelize db:migrate

    前端数据如何往mysql中写?

    调用todo.js模块:

    use strict' ;
    module. exports = (sequelize, DataTypes) => {
    	const Todo = sequelize.define( 'Todo', {
    		name: DataTypes. STRING,
    		deadLine: DataTypes .DATE,
    		content: DataTypes. STRING
    	},{
    		timestamps:false
    	}) ;
    	Todo. associate = function(models) {
    		// associations can be def ined here
    	};	
    	return Todo;
    };

    使用:创建第一个todo:(初始时)

    app.post('/create',async (req,res,next)=>{
    	try{
    		let {name,deadline,content}=req.body;
    		//持久化到数据库
    		let todo=await models.Todo.create({
    			name,
    			deadline,
    			content
    		})
    		res.json({
    			todo,
    			message:'任务创建成功'
    		})
    	}catch(err){
    		next(error)
    	}
    })

    最后的next传给谁?

    我们之前说,在全局最后创建一个use,用于错误处理:

    app.use((err,req,res,next)=>{
    	if(err){
    		res.status(500).json({
    			message:err.message
    		})
    	}
    })

    更多编程相关知识,请访问:编程入门!!

    Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung von Express in NodeJS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen