先creat一个server,index.html是我们的模板,在node不操作dom,bom对象的,通过fs的readfile读取文件,然后res对象的end()发放,把二进制数据或者字符串还给浏览器解析。这边我们通过开放public目录,让客户端可以请求我们的公共静态数据,里面包括css,img,啥的。
先放一下文件目录跟简单代码
var http = require('http')
var fs = require('fs')
http
.createServer(function(req,res){
var url = req.url
if (url==='/'){
fs.readFile('./views/index.html',function(err,data){
if (err) {
return res.end('404 not found')
}
res.end(data)
})
}else if (url.indexOf('/public/')===0) {
// /public/css/main.css
// /public/js/main.js
// 统一处理:
// 如果请求路径是以/public/开头的,则我认为你要获取public中的某个资源
// 所以我们就直接可以把请求路径当作文件路径来进行读取
// 之前这里一直很纠结的是为什么会有else if,在我的印象中好像url选择了'/'就不会再继续执行了,但是其实是我钻牛角尖
// 因为我们这里是个服务器,会不断地接受请求,执行了第一次'/'以后,打开index.html后,会形成新的url发送请求,重建req对象,里面url也是变化的。
// console.log(url)
fs.readFile('.'+url,function(err,data){
if (err) {
return res.end('404 not found')
}
res.end(data)
})
}
})
.listen(3000,function(){
console.log('running')
})
go on
index.html中的大体内容
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="/public/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<hr>
<a href="/post" class="btn btn-success">添加</a>
<hr>
<ul class="list-group">
{{each dataList}}
<li class="list-group-item">{{$value.name}}.Say:{{$value.message}}
<span class="pull-right">{{$value.date}}</span>
</li>
{{/each}}
</ul>
</div>
</body>
</html>
注意:在服务端中,文件的路径就不要去写相对路径了。因为这个时候所有的资源都是通过url标识来获取的,我的服务器开放了/public/目录,所以这里的请求路径都写成:/public/xxx
‘/’在这里就是url根路径的意思。
浏览器在真正发请求的时候会最终把http://127.0.0.1:3000拼上,不要再想文件路径了,把所有的这些路径想象成URL地址,这也是前端渲染根后端渲染的不同
后端可以控制访问文件的路径,如果把public的路径注释掉,即让这段代码失效
fs.readFile(’.’+url,function(err,data){
if (err) {
return res.end(‘404 not found’)
}
res.end(data)
})
那么就无法从url中读取到对应的文件了。再次强调,从服务端出来的href都是url,是url就要给他设定if,访问文件的权限。
回到首页渲染。现在已经用url‘/’读取文件‘index.html’,要把comments数据放到模板引擎里面,需要引进包’art-template’,
var template = require('art-template')
var comments = [
{
name:'zeid',
message:'无形装B,最为致命',
dataTime:'2020.6.1'
},
{
name:'brokenheaven',
message:'i will get crown',
dataTime:'2020.6.1'
},
{
name:'recovery',
message:'do or die',
dataTime:'2020.6.1'
},
{
name:'kitty',
message:'i am a cat with magic power',
dataTime:'2020.6.1'
}
]
var htmlStr = template.render(data.toString(),{
comments:comments
})
res.end(htmlStr)
看到这个变量命名了嘛。htmlStr,最后其实返回给浏览器的是字符串
我们可以看看服务器收到请求后返回的数据
如果注释这三行
// var htmlStr = template.render(data.toString(),{
// comments:comments
// })
我们得到的服务器的res.data也是字符串对象,我截图了,其实跟上面差不多
两个不同res渲染的画面
emmmm。。。这边主要是服务端渲染,到了首页以后点击发表留言按钮跳转到我们留言页面~也就是post.html,当然还是通过Button的href属性通过url,然后fs.readfile(xxx,function(err,data))实现的,后端渲染就是这样的。
<form action="/pinglun" method="get">
<div class="form-group">
<label for="exampleInputEmail1">Yon Name</label>
<input type="text" name="name" class="form-control" id="input_name" minlength="1" placeholder="Yon Name">
</div>
<div class="form-group">
<label for="exampleInputEmail1">message</label>
<textarea name="message" class="form-control" rows="5" id="textarea_message"></textarea>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
这边的提交地址’/pinglun’,点击发表按钮以后,我们的URL请求是这样的
这个url无法判断,后面还有动态的数据,所以只需要判断前面的/pinglun
这时候引进新的模块,'url’模块。。。里面有url.parse()方法,这个方法生成一个对象数据可以帮助解析出pathname
图片里面那个地址就是我ball猫那个url,可以看到pathname可以把’/pinglun‘捞出来,不知道这边可不可以用正则,我还是rookie。因为数据是用户输入的,动态变化的。反正这时候我解析出pathname就可以得知用户提交数据过来了
var url = require('url')
var parseObj = url.parse(req.url,true)
var pathname = parseObj.pathname
else if(pathname === '/pinglun'){
res.setHeader('Content-Type','text/html;charset=utf-8')
res.end(JSON.stringify(parseObj.query))
}
用json格式到我们的数据,使这么长的url也能被识别,以及成功跳转到设定的’/pinglun‘ 条件中
if(pathname === '/pinglun')
往comments数组中添加数据,这个时候不是持久化存储 如果服务端重启就没了嗷,没有连接数据库
var comment = parseObj.query
comment.dataTime = '2020-6-3,23:34'
comments.push(comment)
服务器重定向到首页~如何通过服务器让客户端重定向?状态码302是临时重定向,301永久重定向,在响应头中通过location告诉客户端往哪重定向,如客户端发现服务器的响应码是302就会自动找location,通过setheader
res.statusCode = 302
res.setHeader('Location','/')
到这儿就结束拉~~
挂载到80端口,提供服务器IP地址,就有了一个QQ留言板QAQ哈哈
每天练习一个markdown语法,
我想要只像蛋仔一样的喵喵
醒醒,先搬砖吧!!