经过几天的学习,已经可以用node简单的搭建一个小型局域服务器了,现在总结一下,可以分为以下几个步骤
UI页面布局
简单的写一下就可以了,没什么好说的,主要目的是服务器读取资源的实现
- node实现服务器的步骤:
var http = require('http')
var server = http.createServer()
var fs = require('fs')
server.on('request', function (request,response) {
...
})
server.listen(5000,function () {
console.log('server is running,Port number is 5000')
})
基本步骤是这样,当然具体还有url地址解析等
- 文件列表基本上是这样的
static方各种静态资源,js,imgcss等等
view即视图,存放等会要展示的页面,
app.js是node服务器,在命令行运行node app.js
即可启动服务器 - app.js实现服务器步骤:
var http = require('http')
var server = http.createServer()
var fs = require('fs')
server.on('request', function (request,response) {
var url = request.url
if(url === '/') {
fs.readFile('./view/index.html', function (err,data) {
if(err) {
return response.end('404')
}
response.end(data)
})
}
})
server.listen(5000,function () {
console.log('server is running,Port number is 5000')
})
命令行输入node app.js
启动服务器
结果···
css等一些从外层引进来的文件都没有效果…
#控制台可以看到,两个css文件一直没响应到
这里需要注意的一点是:通过服务器读取资源,即服务器渲染页面,遇到css,js等外联资源就是发送一次请求,所有引用就不能像以前那样用了,而且app.js文件也应该做相应调整
1.所有资源都在服务器端存放,所有客户端的请求都是从最外层文件夹开始读取,都是通过url标识来获取,即所有的路径都是url地址。所以,引用地址不能再写相对路径,而是绝对路径。
·
2.浏览器在收到html响应内容之后,从上到下依次解析,解析的过程中,遇到
link,script,img,iframe,video,audio等
具有src或者href属性的时候,都会对这些资源发起新的请求,新的请求又会触发server.on()
,所以,我们需要对request.url
加以处理
加上判断语句
else if(url !== '/') {
fs.readFile('.' + url, function (err,data) {
if(err) {
return response.end('404')
}
response.end(data)
})
}
如果url地址不是首页,我们直接让fs根据路径读取文件,这里注意url前面的 ‘.’不能省略
此时,页面完美的展现出来了:
接下来,我们要实现的是页面之间的跳转:
这一步很简单,只需要在跳转按钮设置:
href="/post"
app.js加url判断语句:
else if(url === '/post') {
fs.readFile('./view/post.html', function (err,data) {
if(err) {
return response.end('404')
}
response.end(data)
})
搞定
留言页面
还有一点需要注意的,页面渲染内容显然需要模板引擎来实现,其他拼接字符串等方式太笨效率低还容易出错
命令行输入npm install art-template
,下载模板引擎到当前目录,在app.js引入
var template = require('art-template')
我们需要在首页渲染数据,则在判断语句里面加上
//模板引擎渲染数据
data = template.render(data.toString(),{
items: items
})
因为fs读取文件data默认为二进制,我们需要转换成字符串才能被模板引擎解析,故而加上toString()
方法。
需要说明的是,items是我们造的假数据.
var items = [
{
name: '马尔扎哈',
time: '2018-08-16 20:05:42',
email: '15481665@qq.com' ,
content: '中国天气网官方权威发布天气预报,逐三小时天气预报,提供天气预报查询一周,天气预报15天查询'
},
{
name: '马尔扎哈',
time: '2018-08-16 20:05:42',
email: '15481665@qq.com' ,
content: '中国天气网官方权威发布天气预报,逐三小时天气预报,提供天气预报查询一周,天气预报15天查询'
}
]
为了测试,然后在index.html
同样需要设置一下
{{ each items }}
<div class="box">
<span class="first">{{ $value.name }}</span>
<span class="second">{{ $value.time }}</span>
<span class="second">{{ $value.email }}</span>
<p>{{ $value.content }}
</p>
</div>
{{ /each }}
app.js
if(url === '/') {
fs.readFile('./view/index.html', function (err,data) {
if(err) {
return response.end('404')
}
data = template.render(data.toString(),{
items: items
})
response.end(data)
})
}
最后异步,需要在post页面输入东西点击提交,加载到首页并重定向,这里表单提交方式我们选择get,url地址够获取到数据,方便操作
需要引入node的url
,里面包含了好多解析url地址的方法
url地址有一个方法
将url地址转换为方便操作的对象,第二个参数如果是真的,查询属性总是被设置为querystring模块的parse()方法返回的对象。
如果是假的,返回的URL对象上的查询属性将是一个未解析的、未解码的字符串。默认值为false。
var parseObj = url.parse(request.url,true)
,
parseObj
里面包含了许多属性,这里我们能用到的两个:pathname
,query
获取表单提交的数据 parseObj.query
单独获取不包括查询字符串的路径部分(该路径不包含?之后的内容) pathname
- 有了
pathname
,我们就不用request.url
了,用pathname不包含问号后面的数据, - 用get提交的时候,我们只需要用
query
获取用户输入的内容把它追加到数组items
当中去,即可完成添加留言功能
var item = parseObj.query
item.time = new Date()
items.unshift(item)
最后一步,重定向到首页
- 状态吗设置302临时重定向
- 在响应头中通过location告诉客户端重定向路径
response.statusCode = 302
response.setHeader('Location', '/')
response.end()
至此,基本功能已经基本完成,但是服务器重启后数据将不存在,可以利用数据库知识加以完善也可以用localstorage
实现本地存储,等等
最后,附上app.js代码:
var http = require('http')
var server = http.createServer()
var fs = require('fs')
var template = require('art-template')
var url = require('url')
var items = []
server.on('request', function (request,response) {
//将url地址转换为方便操作的对象,第二个参数如果是真的,查询属性总是被设置为querystring模块的parse()方法返回的对象。
// 如果是假的,返回的URL对象上的查询属性将是一个未解析的、未解码的字符串。默认值为false。
var parseObj = url.parse(request.url,true)
var pathname = parseObj.pathname
if(pathname === '/') {
fs.readFile('./view/index.html', function (err,data) {
if(err) {
return response.end('404')
}
data = template.render(data.toString(),{
items: items
})
response.end(data)
})
} else if(pathname === '/post') {
fs.readFile('./view/post.html', function (err,data) {
if(err) {
return response.end('404')
}
response.end(data)
})
} else if(pathname.indexOf('/static') === 0) {
fs.readFile('.' + pathname, function (err,data) {
if(err) {
return response.end('404')
}
response.end(data)
})
} else if(pathname === '/comment') {
var item = parseObj.query
item.time = new Date()
items.unshift(item)
//重定向跳转到首页
response.statusCode = 302
response.setHeader('Location', '/')
response.end()
}
})
server.listen(5000,function () {
console.log('server is running,Port number is 5000')
})
·