首先下载安装node.js
本文从基本开始搭建,(详细1)步骤不出错的情况下基本实现接口配置,请求传参与接收。
新建一个文件夹,命名为serve
,在该文件下创建app.js
子文件,此为服务器入口
内容比较冗长,请慎重食用
在serve目录下运行
npm init -y
你会在根目录下得到一个package.json
的文件
或者通过
npm init
可能在命令行中会逐行提示
一直回车,直到出现后输入Y
同样能够得到package.json
文件
得到package.json
文件后,就可以在app.js
中创建服务器了
创建服务器需要导入模块,而node.js导入模块有三种方式
1、amd(require.js)
2、cmd(sea.js)
3、es6(import)
我们使用require的方式
开始引入
先看最原始配置
const prot = 3000; // 端口号
const hostName = '127.0.0.1'; //代理服务器主机名
const myhttp = require('http'); //服务器-浏览器交互遵循http协议,导入http模块,此为node自带
const myserver = myhttp.createServer((req,res)=>{
//通过http模块的createServer方法去创建服务,req为请求对象, res为响应对象
console.log('server running')
})
myserver.listen(prot,hostName,function(){
console.log(`server running.... at ${hostName}:${prot}`)
})
//通过http的的listen方法去监听服务器运行,这里console.log的内容可以不用顾虑,只是模板字符串的变量引入,不作讲解
有了基本配置之后,就可以开启服务器运行了,通过右键,Run app.js
或者
在serve目录下命令行运行node app.js
命令行得到
则运行成功,这只是listen
方法监听到服务器已经开始运行,如想要访问该服务器,在浏览器窗口打开at后的接口地址,复制时不要忘了端口号
再查看命令行,会发现
服务器有了动静,就说明访问服务器已经成功了
可能这时候你发现了:
有想法的小伙伴可以打印一下res
和req
来看一下,注意,这里打印的话会得到一大串的服务器内容
我们配置后端服务器,想要实现的效果就是在请求接口地址的时候,服务器对这个请求进行接收并响应,然后返回给浏览器,你的命令行打印出了server running
,就说明我们这个服务器已经接收到了你浏览器发起的请求。
再看你的浏览器窗口,会发现,你的浏览器正一直处于等待响应状态,这就是因为服务器已经接收到了你的请求,但是你并没有跟它答复。
那我们就开始设置对这个浏览器请求进行的响应:
const myserver = myhttp.createServer((req,res)=>{ //通过myserver去http模块的createServer方法去创建服务,req为请求对象, res为响应对象
res.setHeader('Content-Type','text/plain'); //设置响应头
res.end('response your information') //结束响应信息
})
响应头是为了告知浏览器,你传递回去的是个什么玩意
设置完之后,不要忘了重启服务器
,如果是通过命令行的,你可以使用Ctrl + c
强制中断,输入y
确定关闭服务,在重新在命令行输入node app.js
即可,如果是用过按钮开启,
在ide最下方找到Run栏目,点重启按钮。
再次访问该服务接口地址,你会发现
服务器接收到了你响应的内容。
这节要做的目的就是向浏览器发送请求后,浏览器返回一个html
文件,并解析显示为页面
虽然我们现在做到了浏览器与服务器的简单交互,但我们最主要的是想要实现他们之间的数据交互
,做到目前,肯定是远远不够的。
简单请求参数携带:
类似通常的get
请求,我们将参数拼接在浏览器的接口地址后,类似
传递index.html到服务器
这个时候,服务器接收到的信息都在请求对象(req)
里边,我们可以通过搜索url
,找到我们需要的信息
同样,也可以找到headers
这就是浏览器发起的请求头文件数据。
我们打印一下req.url
就做到了简单的参数接收。
注意:必须通过‘/’
分隔
我们可以对这个返回的数据进行判断或是处理,在什么样的请求参数下,我们需要返回什么样的数据
// fs.readFile('文件路径',文件解析方式,回调函数)
我们在根目录serve
下新建一个src
子文件,用于存放静态资源,html文件,css文件,js文件,图片等
子文件下再新建一个index.html文件,在这个html中输入一点内容,例如:
修改app.js
这里路径不绝对,根据自己情况而定,如果打印data得出的结果是undefined
,那证明路径出错,改为src/index.html
试试
// fs.readFile('文件路径',文件解析方式,回调函数)
fs.readFile('VueDemo/serve/src/index.html','utf-8',(err,data)=>{
console.log('读取信息',data);
})
重新运行,浏览器请求打开,命令行会得到你index
中的html内容
可能你会觉得,这时候,使用上边的方法,res.end
是不是就能完成我们想要的效果呢?并不是,因为你现在得到的内容其实只是一个字符串,通过res.end发送过去,浏览器就会直接给你解析为字符串并展示在当前页面上
要是我们需要将这个文件响应回去,就单是发送为字符串了,我们需要设置响应头
一般响应有三个步骤
1、设置响应头
//res.writeHead(响应状态码,'配置解析方法,告诉浏览器这个文件你要解析成啥样')
res.writeHead(200,{'Content-Type':'Text/Html;Chartset=utf-8'})
2、发送
//res.write(你的文件对象)
res.write(data)
3、发送结束
res.end()
//告知浏览器你的这次响应结束
设置完这三个步骤后,再次重启服务器,在浏览器发起请求会得到
特例
我们在src文件中新建css
和js
子文件,并在子文件下各自新建index.css
和index.js
文件,css文件中设置一个文字样式,表明引入成功
在html文件中引入他们
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
hello word
<script src="./js/index.js"></script>
</body>
</html>
直接打开该html文件:
在html文件中的css样式文件引入成功
我们发现,浏览器一直处于等待响应状态,而我们的命令行打印的req.url
似乎除了index.html
这个请求之外,还多了css
和js
的请求
这是由于浏览器在解析你的html文件的时候发现了你接入的外部css和js文件,它就再次向浏览器发起请求,企图得到这些外部文件的响应;
这时候其实在我们的服务器当中,这些文件都存在,我们只需要向浏览器再次响应就好了
const myserver = myhttp.createServer((req,res)=>{ //通过myserver去http模块的createServer方法去创建服务,req为请求对象, res为响应对象
res.setHeader('Content-Type','text/plain');
console.log(req.url);
if (req.url=='/index.html') {
// fs.readFile('文件路径',文件解析方式,回调函数)
fs.readFile('VueDemo/serve/src/index.html','utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/Html;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(req.url=='/css/index.css'){
fs.readFile('VueDemo/serve/src/css/index.css','utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/css;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(req.url=='/js/index.js'){
fs.readFile('VueDemo/serve/src/js/index.js','utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/javascript;Chartset=utf-8'})
res.write(data);
res.end()
})
}
})
这里分别对响应的读取文件路径,解析格式进行了更改
分别判断请求文件格式,在对每次请求进行响应
重启服务,我们再次请求就得到
可能你会觉得,上边那种一个文件一个文件进行判断的方法非常辣鸡,而且一旦遇上有外部a
标签的时候,点击这个a标签,这种方法就跟坨s一样,又需要重新去判断,这时候,你可以把url路径进行拆分,得到后缀后进行封装
修改后得到
这里使用了模板字符串
与模板字符串的引入变量
const myserver = myhttp.createServer((req,res)=>{ //通过myserver去http模块的createServer方法去创建服务,req为请求对象, res为响应对象
res.setHeader('Content-Type','text/plain');
let fileType = req.url.split('.');
if (fileType[1]=='html') {
// fs.readFile('文件路径',文件解析方式,回调函数)
fs.readFile(`VueDemo/serve/src/${fileType[0]}.html`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/Html;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(fileType[1]=='css'){
fs.readFile(`VueDemo/serve/src/${fileType[0]}.css`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/css;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(fileType[1]=='js'){
fs.readFile(`VueDemo/serve/src/${fileType[0]}.js`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/javascript;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(fileType[1]=='jpg' || fileType[1]=='png'){//或者更多种类
fs.readFile(`VueDemo/serve/src/${fileType}`,(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/javascript;Chartset=utf-8'})
res.write(data);
res.end()
})
}
})
重启尝试,依旧得到
这样使用后,如果遇上了a标签,也能进行正常跳转,他会根据你的请求文件后最,在整个src目录下进行查找,并响应,对比之上,就要相对简洁方便很多,常用静态资源还有image,但是image的后缀颇多
再次简单更改
const myserver = myhttp.createServer((req,res)=>{ //通过myserver去http模块的createServer方法去创建服务,req为请求对象, res为响应对象
res.setHeader('Content-Type','text/plain');
let fileType = req.url.split('.');
if (fileType[1]=='html') {
// fs.readFile('文件路径',文件解析方式,回调函数)
fs.readFile(`VueDemo/serve/src/${fileType[0]}.html`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/Html;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(fileType[1]=='css'){
fs.readFile(`VueDemo/serve/src/${fileType[0]}.css`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/css;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(fileType[1]=='js'){
fs.readFile(`VueDemo/serve/src/${fileType[0]}.js`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/javascript;Chartset=utf-8'})
res.write(data);
res.end()
})
}else if(fileType[1]=='jpg' || fileType[1]=='png'){//或者更多种类
fs.readFile(`VueDemo/serve/src/${fileType}`,(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/javascript;Chartset=utf-8'})
res.write(data);
res.end()
})
}
})
在此之前,如果你跟着我敲了上述的代码,你就会发现,当服务器接收到浏览器发送过来的请求之后,我们仅仅只响应回了静态资源,
而分层的作用就是将我们的拦截功能分发出去,单独分一个文件用作功能/数据/请求处理,我们在根目录serve
下新建一个文件命名为controller
并在该文件下新建子文件indexCtrl.js
在此之前,我们所有响应处理都在myhttp.createServer
的箭头函数中进行,现在我们把中间内容剔除出去,放在indexCtrl.js
文件中
const fs = require('fs')
module.exports = {
sendHtml(url,res){
fs.readFile(`VueDemo/serve/src/${url}.html`,'utf-8',(err,data)=>{
console.log(data)
res.writeHead(200,{'Content-Type':'Text/Html;Chartset=utf-8'})
res.write(data);
res.end()
})
},
sendCss(url,res){
fs.readFile(`VueDemo/serve/src/${url}.css`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/css;Chartset=utf-8'})
res.write(data);
res.end()
})
},
sendJs(url,res){
fs.readFile(`VueDemo/serve/src/${url}.js`,'utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/javascript;Chartset=utf-8'})
res.write(data);
res.end()
})
},
sendImg(url,res){
fs.readFile(`VueDemo/serve/src/${url}`,(err,data)=>{
res.writeHead(200,{'Content-Type':'Text/javascript;Chartset=utf-8'})
res.write(data);
res.end()
})
}
}
indexCtrl
这里专门为了四个方法,然后通过module.exports
把它们公开,在app.js中引入,将响应对象res
和解析路径url作为参数传递给这四个方法,四个方法在分别处理,app.js修改为这样
const prot = 3000; // 端口号
const hostName = '127.0.0.1'; //代理服务器主机名
const myhttp = require('http'); //服务器-浏览器交互遵循http协议,导入http模块,此为node自带
const contrl = require('./controller/indexCtrl')
const myserver = myhttp.createServer((req,res)=>{ //通过myserver去http模块的createServer方法去创建服务,req为请求对象, res为响应对象
res.setHeader('Content-Type','text/plain');
let fileType = req.url.split('.');
if (fileType[1]=='html') {
contrl.sendHtml(fileType[0],res)
}else if(fileType[1]=='css'){
contrl.sendCss(fileType[0],res)
}else if(fileType[1]=='js'){
contrl.sendJs(fileType[0],res)
}else if(fileType[1]=='jpg' || fileType[1]=='png'){
contrl.sendJs(fileType[0],res)
}
})
myserver.listen(prot,hostName,()=>{
console.log(`server running.... at ${hostName}:${prot}`)
})
如果再简写,也可以将请求对象req
也作为参数传递过去,所有判断全部放在indexCtrl.js
中作处理,但是这些都比较冗余,没有必须一一再写,一一再分析,目前也可以实现同样的效果;
做到这一步,其实如果在前后端不分离的状态下,我们就已经可以实现 搭建服务器+访问服务器文件 了,但似乎还不够。
重启并访问
你可能会觉得,原本一个文件可以解决的问题,为什么需要分这个包那个包的多麻烦,慢慢看,你会明白的
自使用了indexCtrl.js
后,我们把数据处理的功能划到了其中,其主要功能其实就是 响应/返回
文件/数据,紧接着是router
,如果有Vue
或者react
基础的可能对这个并不陌生,router
的主要作用就是请求拦截,它判断你浏览器发起了一个什么样的请求,所请求的是什么样的内容,然后将这个结果分发给controller
层去处理。
上述,我们在myhttp.createServer
中进行了url路径判断,其实我们所要做的就是把这个判断拆分到router
层即可。
在serve文件下新建routers
文件,新建子文件indexRouter.js
const contrl = require('../controller/indexCtrl')
module.exports={
pageRoute(req,res){
let fileType = req.url.split('.');
if (fileType[1]=='html') {
contrl.sendHtml(fileType[0],res)
}else if(fileType[1]=='css'){
contrl.sendCss(fileType[0],res)
}else if(fileType[1]=='js'){
contrl.sendJs(fileType[0],res)
}else if(fileType[1]=='jpg' || fileType[1]=='png'){
contrl.sendJs(fileType[0],res)
}
}
}
因为这个文件需要使用controller中的四个方法,所以我们需要将其引入,同理,我们需要引入indexRouter.js
到app.js中,这时候我们的入口文件就看起来简便很多。
const prot = 3000; // 端口号
const hostName = '127.0.0.1'; //代理服务器主机名
const myhttp = require('http'); //服务器-浏览器交互遵循http协议,导入http模块,此为node自带
const routers = require('./routers/indexRoter')
const myserver = myhttp.createServer((req,res)=>{ //通过myserver去http模块的createServer方法去创建服务,req为请求对象, res为响应对象
res.setHeader('Content-Type','text/plain');
routers.pageRoute(req,res)
})
myserver.listen(prot,hostName,()=>{
console.log(`server running.... at ${hostName}:${prot}`)
})
再次重启访问,依旧能得到相同的效果
我们虽然是将一个文件拆分成了三个文件,,router文件专门用作请求处理,controller专门作响应处理,他们直接全部通过require
建立连接,不仅仅是为了让入口文件app.js看起来更简洁,更是为了让他们的功能更加明确,这就是分层的目的。
可以看一下express介绍,它是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用。
目的:使用express配置get请求接口
安装:命令行输入:npm install express -s
使用:
之前我们构建服务器:
const myhttp = require('http');
const myserver = myhttp.createServer((req,res)=>{ })
myserver.listen(prot,hostName,()=>{})
现在有了express构建服务器:
const express = require('express')
const myserver = express()
myserver.listen(prot,hostName,()=>{})
以上是最基本的内容,紧接着我们导入日志模块morgan
,你可能有听说过 ‘日志’ 这个内容,主要作用就是记录服务器的每次访问,耗时、请求方式、请求内容等,有这样一个模块,相当于我们已经对服务器的访问进行监听了。
当然,也需要安装:
npm install morgan -s
在这里接入新的内容,app.use()
其本质就是将模块 挂载 在服务器上,使服务器可以调用模块的方法。
引入了日志模块后,我们的app.js现在是这样的:
const prot = 3000; // 端口号
const hostName = '127.0.0.1'; //代理服务器主机名
const express = require('express');
const morgan= require('morgan');
const myserver = express();
myserver.use(morgan('dev'));
//将morgan挂载在服务器,并将监听内容打印在控制台
myserver.use(express.static(__dirname+'/src'));
//挂载使用express的static方法,__dirname 相当于当前目录的根目录,其作用是在根目录下的src文件夹内查找服务器所请求的文件
myserver.listen(prot,hostName,()=>{
console.log(`server running.... at ${hostName}:${prot}`)
})
如果不需要日志,只需取消morgan
的使用即可,当然,不建议取消日志模块的使用。
重启访问:
控制台日志显示
分别代表 请求方式(get) - 请求文件 - 请求状态码 - 请求耗时
因为我们使用了express.static(__dirname+'/src')
,他会浏览器发起请求的时候去查找src目录,判断是否有存在的文件,如果有,就直接响应给了浏览器,虽然这只是查找src直接子级目录,但浏览器在接收到响应的src目录下index.html
文件后,也同样通过当前idex.html的引用路径重新向服务器发起了请求,最终得到css与js文件的响应。
虽然似乎实现了没有使用express
时候的效果,但我们也去掉了router+controller功能细分,你可能会说,那我之前讲的都是屁话,慢慢来,之后还有机会用到这些内容。
get
请求拦截总算到重点部分
为了验证我们的get请求,我们要设置一下内容的提交,只需要在原本的idnex.html文件中进行更改就可以:
如果你能看到这里,说明你对前端也有一定的了解,我就不一一讲解form表单提交了,/login
是我们的提交地址,get
是我们的提交方法
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="stylesheet" href="./css/index.css">
head>
<body>
hello word
<form action="/login" method="get">
用户名:<input type="text" name="username">
密码:<input type="password" name="pwd">
<button>提交button>
form>
<script src="./js/index.js">script>
body>
html>
myserver.get('/login',(req,res)=>{
console.log(req.url)
})
调用express的get方法 (myserver是用过express构建的服务器),get(‘接口名称’,请求响应处理方法)
这时候我们的app.js入口文件是这样的:
const prot = 3000; // 端口号
const hostName = '127.0.0.1'; //代理服务器主机名
const express = require('express');
const morgan = require('morgan');
const myserver = express();
myserver.use(morgan('dev'));
myserver.use(express.static(__dirname+'/src'));
myserver.get('/login',(req,res)=>{
console.log(req.url)
})
myserver.listen(prot,hostName,()=>{
console.log(`server running.... at ${hostName}:${prot}`)
})
重启服务,刷新浏览器,分别输入用户名为admin
,密码为admin
点击提交
得到
证明我们的接口地址已经发起了请求,服务器也拦截到了这个请求,在我们点击提交后,浏览器也一直处于等待响应状态
所以我们需要对这个请求进行响应配置,这是不是好像又回到了我们最开始的内容,请求处理
与响应处理
!
获取参数
:
虽然我们似乎已经拿到了用户提交的用户名与密码,但这并不是我们想要的格式
我们再次打印请求对象req
,搜索后可以找到json格式对象,query
,
想要拿到其中的内容,就可以直接:req.query.username
更改:
myserver.get('/login',(req,res)=>{
let username = req.query.username;
let pwd = req.query.pwd;
console.log('用户名:',username,'用户密码:',pwd)
})
重启服务,刷新浏览器,重新输入并请求:
由于我们暂时还没有连接到数据空,所以我们只是做一个假定的判断,根据获取到的内容,响应响应的值或者状态:
myserver.get('/login',(req,res)=>{
let username = req.query.username;
let pwd = req.query.pwd;
console.log('用户名:',username,'用户密码:',pwd)
if (username == 'admin'&& pwd == 'admin'){
res.send('登陆成功')
}else{
res.send('登陆失败')
}
})
我们通过响应对象的send
方法,将响应成功的状态发送给浏览器,这里的send方法返回的内容,可以是float
,可以是number
,也可以是object
,或者是其他
更改完成后我们重启服务器,再刷新浏览器,输入 正确/错误 内容后提交
到这一步之后,我们延续之前的步骤,将这个验证的过程交给router
文件去处理
导入router,并挂载在服务器上: 在app.js
中插入
const router = require('./routers/indexRoter');
myserver.use(router)
express已经给我们提供了路由方法,所以我们需要更改我们的indexRouter.js
文件:
const express = require('express');
const expressRouter = express.Router();
const indexCtrl = require('../controller/indexCtrl');
expressRouter.get('/login',indexCtrl.login)
//这里是直接引用了controller层indexCtrl.js中的login方法
module.exports = expressRouter
并将判断部分划给controller文件,
module.exports = {
login(req,res){
let username = req.query.username;
let pwd = req.query.pwd;
if (username == 'admin'&& pwd == 'admin'){
res.send('登陆成功')
}else {
res.send('登陆失败')
}
}
}
剔除了判断部分,我们的入口文件app.js
就变为:
const prot = 3000; // 端口号
const hostName = '127.0.0.1'; //代理服务器主机名
const express = require('express');
const morgan = require('morgan');
const myserver = express();
const router = require('./routers/indexRoter');
myserver.use(router)
myserver.use(morgan('dev'));
myserver.use(express.static(__dirname+'/src'));
myserver.listen(prot,hostName,()=>{
console.log(`server running.... at ${hostName}:${prot}`)
})
再次重启服务器,刷新浏览器,提交内容,也可以得到相同的结果!
如果此时,通过其他域转接访问,会出现跨域问题,不通过转接访问的可以跳过这步,如果出现该问题,用node.js解决的方法就是下载cors
模块,并路由文件中引入:
问题例子:
使用方法
const express = require('express');
const expressRouter = express.Router();
const cors = require('cors')
const indexCtrl = require('../controller/indexCtrl');
expressRouter.get('/login',cors(),indexCtrl.login)
module.exports = expressRouter
get请求与post请求的区别
body-parser解析post请求参数
安装:npm install body-parser -s
引入: const bodyParser = require('body-parser'); //用作解析
挂载:
myserver.use(bodyParser.json()); //将其解析为json格式
myserver.use(bodyParser.urlencoded({extended:false})); //挂载配置post解析body模块
引入解析之后,在处理响应对象的controller层,打印获取参数,就不再是req.query
,而是 req.body
注:如果使用req.body打印出的内容为undefined
或是空对象{}
,记得把中间件挂载提前,完整:
入口文件app.js
:
const prot = 3000; // 端口号
const hostName = '127.0.0.1'; //代理服务器主机名
const express = require('express');
const morgan = require('morgan'); //日志模块
const myserver = express(); //以express构建服务器
const indexRouter = require('./routers/indexRoter');//路由层文件 用做判断处理请求对象然后分发给controller层
const bodyParser = require('body-parser');//用作解析
myserver.use(bodyParser.json()); //将其解析为json格式
myserver.use(bodyParser.urlencoded({extended:false})); //挂载配置post解析bodym模块
myserver.use(indexRouter); //挂载路由
myserver.use(morgan('dev')); //挂载日志模块
myserver.use(express.static(__dirname+'/src')); //查找src目录
myserver.listen(prot,hostName,()=>{
console.log(`server running.... at ${hostName}:${prot}`)
})
indexCtrl.js
:
login(req,res){
let username = req.body.username;
let pwd = req.body.pwd;
let data = {
state:200,
success:true,
message:'登陆成功'
}
if (username == 'admin'&& pwd == 'admin'){
res.send(data)
}else {
data.state = -1;
data.success = false;
data.message='登陆失败';
res.send(data)
}
}
这里作了一点小更改,把原本返回的数据状态,改成了一个对象
切记,全部改为post之后,router文件,html文件也要随着改变:
indexRouter.js
const express = require('express');
const expressRouter = express.Router();
const indexCtrl = require('../controller/indexCtrl');
expressRouter.get('/login',indexCtrl.login);
expressRouter.post('/loginP',indexCtrl.login);
module.exports = expressRouter
<form action="/loginP" method="post">
用户名:<input type="text" name="username">
密码:<input type="password" name="pwd">
<button>提交button>
form>
全部更改完成后,可重启服务,刷新浏览器,重新输入内容并提交。
(未完待续)