简介
对于前端(Front-End)来说,开发语言方面有且只有HTML、CSS、JavaScript这三种,至于VUE之类的框架也无非是基于这些语言之上的拓展。
而对于后端(Back-End)来说,可用的开发语言就很多了,例如我常用的Python、最常用的PHP、经久不衰的Java、.Net、Ruby、Go等等,各有自己的特色。
而今天的主角,就是后端开发语言中的后起之秀Node.js。
有句话叫做,凡是能用JavaScript来实现的应用,最终都会用JavaScript来实现。
而Node.js其实就是一个构建于Chrome V8 引擎之上的JavaScript运行环境,可以在非浏览器的环境下解析和执行JavaScript代码。
相对于浏览器中的JavaScript来说,Node.js拥有相同的EcmaScript语法,但不存在BOM和DOM(不能访问所谓的网页元素),但新增了浏览器缺乏的文件读写、网络服务等服务器级别的后端API。
Node.js的特色是event-driven(事件驱动)、non-blocking I/O model(非阻塞IO模型)、lightweight and efficient(轻量高效),可以通过npm这个方便的开源包管理工具管理第三方开源包。
安装
安装的话很简单,可以去官网下载安装,目前最新版本已经到了15.4,注意由于14.X版本开始不再支持Windows7系统,因此如果是Windows7系统可以到历史版本中选择13.X等早期版本安装。
安装完成后直接在命令行中输入node运行,如果顺利进入Node.js的命令行界面就说明安装成功。
导入模块
在Node.js中,较常用的核心模块有fs(文件操作)、http(http服务)、path(路径操作)、os(操作系统信息)等,可以通过require()方式导入使用。
用户自定义或者下载的其他模块,也可以通过require()方式导入使用(类似Python的import),相对路径的“./”不能省略,但可以省略“.js”后缀名。
另外传统的JavaScript只能通过HTML页面中的script标签来导入第三方模块,而在Node.js中可以通过@import()
方式引用其他js文件中的函数。
文件读写
在Node.js中如果想要进行文件操作,必须要引入fs这个核心模块,它提供了文件操作相关的API。
// 加载fs核心模块 var fs = require('fs')
读取文件
fs.readFile('test.txt',function(error,data){ if (data){ console.log(data.toString()) } })
读取到的是文件的二进制内容,因此需要toString转码,或者读取时使用utf8编码。
fs.readFile('test.txt', 'utf8', function(error,data){ if (data){ console.log(data) } })
写入文件
fs.writeFile('E:/new.txt','fdsfdsfdsfgfdhdrhrefhrtntgrm tjnr',function(error){ if (error){ console.log('Write failed!'); } })
传统http服务
使用http核心模块创建http服务
var http = require('http') var server = http.createServer() server.on('request',function(request,response){ console.log('Receive a request:' + request.url) //设置utf-8编码,防止中文乱码 response.setHeader('Content-Type','text/plain;charset=utf-8') response.write('hello nodejs') response.end() // 或者直接写成response.end('hello nodejs') }) server.listen(3000,function(){ console.log('Server started!') })
注意response只能返回字符串格式,因此json格式数据需要使用JSON.stringfy()格式化为字符串,前端收到后使用JSON.parse()再进行解析。
解析前端提交的数据
以下为get方式提交的数据处理方式
var url = require('url') var urlObj = new URL('http://127.0.0.1:3000/get?name=node') // 如果路径不完整的话需要拼合路径如下 // var urlObj = new URL('/get?name=node','http://127.0.0.1:3000/') console.log(urlObj.searchParams.get('name'))
url会被处理成如下形式:
URL { href: 'http://127.0.0.1:3000/get?name=node&type=web', origin: 'http://127.0.0.1:3000', protocol: 'http:', username: '', password: '', host: '127.0.0.1:3000', hostname: '127.0.0.1', port: '3000', pathname: '/get', search: '?name=node&type=web', searchParams: URLSearchParams { 'name' => 'node', 'type' => 'web' }, hash: '' }
这样就可以方便的处理请求和数据了。
重定向
在网站开发中经常会有重定向到某个页面等的需求,此时可以通过302临时重定向状态码实现,在响应头中通过Location告诉客户端重定向的目标网址。
response.statusCode = 302 response.setHeader('Location','/') response.end()
在Node.js中使用模板引擎
以常用的art-template模板引擎为例
//安装 npm install art-template
//使用 var template = require('art-template') var res = template.render('hello {{ name }}', { name: 'Node' }) console.log(res) // hello Node
使用express库创建http服务
express是一个简洁灵活的Node.js Web应用框架,可以快速创建http服务。
//安装 npm install express
使用起来也很方便
var express = require('express') var path = require('path') var app = express() // 公开目录 app.use('/public/',express.static(path.join(__dirname, './public/'))) // http://127.0.0.1:3000/public/img/test.jpg // 或者简写为 // app.use(express.static(path.join(__dirname, './public/'))) // http://127.0.0.1:3000/img/test.jpg app.get('/',function(req,res){ res.send('你好 express') }) app.post('/login/',function(req,res){ res.send('欢迎登陆') }) app.listen(3000,function(){ console.log('listening 3000') })
可以看到可以方便地创建多个request url,快速地公开指定目录的资源,并且省去了处理url、编码、处理404等步骤,代码更加简洁灵活。
express中使用art-template模板引擎
// 安装 npm install art-template express-art-template
基础使用
var express = require('express') var app = express() // 当加载.art的模板文件时,使用express-art-template模板引擎 app.engine('art',require('express-art-template')) // 默认会到views文件夹中寻找模板文件,也可以设置views文件夹路径 app.set('views','./templates/') app.get('/',function(req,res){ res.render('home.art') }) // 方便地获取前端提交的数据以及重定向 app.get('/input',function(req,res){ console.log(req.query) res.redirect('/') }) app.listen(3000,function(){ console.log('listening 3000') })
获取post数据
如果需要获取post的数据的话,需要另一个第三方库body-parser的配合。
// 安装 npm install body-parser //使用 var express = require('express') var bodyParser = require('body-parser') var app = express() app.use(bodyParser.urlencoded({ extended: false})) // 当前端提交的数据为json格式时 app.use(bodyParser.json()) app.post('/post',function(req,res){ console.log(req.body) }) app.listen(3000,function(){ console.log('listening 3000') })
路由表单独定义
在有很多路由时,可以将路由表单独放到一个js文件中,在app.js入口处导入。
// router.js var express = require('express') var router = express.Router() router.get('/',function(req,res){ ... }) module.exports = router
// app.js var express = require('express') var app = express() var routers = require('./router') app.use(routers) app.listen(3000,function(){ console.log('listening 3000') })
注意
1.Node.js中没有全局作用域,只有模块作用域,每一个js文件都是封闭的作用域。
如果需要获取自定义模块中的成员(变量和函数等),那么可以将该成员挂载到默认的exports对象上。
// b.js var foo = "bbb" exports.foo = foo //a.js var b = require('./b') console.log(b) //output { foo: 'bbb' }
这个方式也用于在b中调用a的成员,但是调用到的代码中如果有引用库,那么也得在b中引入。
// b.js module.exports = function (apps) { apps.do() } //a.js var app = function () {...} var b = require('./b') b(app)
2.当使用无分号的代码风格时,若一行代码以(、[、`开头,则须在前面补上分号,避免可能的解析错误问题。
function say () {...} say() ;(function(){})()
3.在开发中,需要频繁重启node服务查看修改效果,可以使用nodemon这个第三方库,能检测到代码修改自动重启服务。
// 安装 npm install nodemon // 使用 nodemon app.js
很多人觉得他们在思考,
实际上只是重新整理自己的偏见。
——弗朗西斯·培
评论
还没有任何评论,你来说两句吧!