node.js基础知识入门
1.模块化
为提高代码的可维护性和复用性,提出了模块化的概念。使用模块化的概念可以避免函数名和变量名的冲突。因为相同名字的函数和变量完全可以分别存在不同的模块中。
在Node环境中,一个.js文件就称之为一个模块(module),模块的名字就是文件名。
导出命令
例如这里编写了一个hello.JS的文件
‘use strict’;
function greet(name) {
console.log(“hello”+name);
}
module.exports = greet;
导入命令
在这里对hello模块进行引入
‘use strict’;
// 引入hello模块:
var greet = require(’./hello’);
greet(‘join’); // Hello, join
在上面这个例子中用到了两个命令一个是模块的导出一个人是模块的导入。同时在此模块的编写中还启用了严格模式。
// 严格模式
'use strict';
// 导出命令
module.exports = greet;
// 导入命令
var greet = require('./hello');
在导入模块的时候,其返回值就是导入模块导出的内容。同时导入的文件名带不带JS都是可以的。
在模块进行导出时,一个模块只能导出一次。当需要导出多个内容时可以使用数组或对象。
2.文件系统
Node.js内置的fs模块就是文件系统模块,负责读写文件。
和所有其它JavaScript模块不同的是,fs模块同时提供了异步和同步的方法。
同步操作的好处是代码简单,缺点是程序将等待IO操作,在等待时间内,无法响应其它任何事件。而异步读取不用等待IO操作,但代码较麻烦。
异步读文件
'use strict';
var fs = require('fs');
fs.readFile('sample.txt', 'utf8', function (err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
readFile
参数设置:目标文件,编码格式,回调函数(err,data)。
同步读文件
除了标准的异步读取模式外,fs也提供相应的同步读取函数。同步读取的函数和异步函数相比,多了一个Sync后缀,并且不接收回调函数,函数直接返回结果。
用fs模块同步读取一个文本文件的代码如下:
'use strict';
var fs = require('fs');
var data = fs.readFileSync('sample.txt', 'utf-8');
console.log(data);
如果同步读取文件发生错误,则需要用try…catch捕获该错误:
try {
var data = fs.readFileSync('sample.txt', 'utf-8');
console.log(data);
} catch (err) {
// 出错了
}
异步写文件
将数据写入文件是通过fs.writeFile()
实现的:
'use strict';
var fs = require('fs');
var data = 'Hello, Node.js';
fs.writeFile('output.txt', data, function (err) {
if (err) {
console.log(err);
} else {
console.log('ok.');
}
});
writeFile()的参数依次为文件名、数据和回调函数。如果传入的数据是String,默认按UTF-8编码写入文本文件,如果传入的参数是Buffer,则写入的是二进制文件。回调函数由于只关心成功与否,因此只需要一个err参数。
和readFile()类似,writeFile()也有一个同步方法,叫writeFileSync()
:
同步写文件
'use strict';
var fs = require('fs');
var data = 'Hello, Node.js';
fs.writeFileSync('output.txt', data);
在fs模块中,提供同步方法是为了方便使用。那我们到底是应该用异步方法还是同步方法呢?
由于Node环境执行的JavaScript代码是服务器端代码,所以,绝大部分需要在服务器运行期反复执行业务逻辑的代码,必须使用异步代码,否则,同步代码在执行时期,服务器将停止响应,因为JavaScript只有一个执行线程。
服务器启动时如果需要读取配置文件,或者结束时需要写入到状态文件时,可以使用同步代码,因为这些代码只在启动和结束时执行一次,不影响服务器正常运行时的异步执行。
当在使用异步方法的时候,为了解决异步的问题我们可以使用回调函数或Promise对象。
3.HTTP模块
Node.js自带的http模块提供了request
和response
对象。
request对象封装了HTTP请求,我们调用request对象的属性和方法就可以拿到所有HTTP请求的信息;
response对象封装了HTTP响应,我们操作response对象的方法,就可以把HTTP响应返回给浏览器。
模块导入
// 导入http模块:
var http = require('http');
// 创建http server,并传入回调函数:
// console.log(http);
//通过request对象,获取所有的HTTP请求信息
//response对象,将数据相应给客户端
//创建服务器 需要接受一个回调函数作为参数 该函数有两个参数 request ,response
let server=http.createServer((request,response)=>{
response.setHeader('Access-Control-Allow-Origin',"*");
//..接收客户端请求
//..响应客户端请求
response.end("hello world !");//响应结束
});
//listen方法接收两个参数 端口号,err
server.listen(9000,err=>{
//不发生错误,err无值,,发生错误,有数据
if(err){
console.log('发生错误:',err);
}
});
console.log('Server is running.......');
http.ServerRequest 是 HTTP 请求的信息,由http.Server 的 request 事件发送,作为第一个参数传递,通常简称 request 或 req。HTTP 请求一般可以分为两部分: 请求头(Request Header)和请求体(Requset Body)。
参数含义
response.writeHead
(statusCode, [headers]):向请求的客户端发送响应头。
statusCode 是 HTTP 状态码,如 200 (请求成功)、 404 (未找到)等。 headers
是一个类似关联数组的对象,表示响应头的每个属性。该函数在一个请求内最多只
能调用一次,如果不调用,则会自动生成一个响应头。
response.write
(data, [encoding]):向请求的客户端发送响应内容。 data 是
一个 Buffer 或字符串,表示要发送的内容。如果 data 是字符串,那么需要指定
encoding 来说明它的编码方式,默认是 utf-8。在 response.end 调用之前,
response.write 可以被多次调用。
response.end
([data], [encoding]):结束响应,告知客户端所有发送已经完
成。当所有要返回的内容发送完毕的时候,该函数 必须 被调用一次。它接受两个可
选参数,意义和 response.write 相同。如果不调用该函数,客户端将永远处于
等待状态。
客户端发送的请求数据
fetch
是一个可以从程序向服务器发起HTTP请求的技术,其返回值是一个promise
对象,可以通多.then()
来接受后台响应的数据。
前端请求的数据分为两种一种是get
数据一种是post
数据。
get
数据是通过地址栏进行传参,在端口号后面通过?进行拼接。
//前端请求
fetch(`http://localhost:9000/?name=${account.value}&pwd=${pwd.value}`)
.then(data => data.json())
.then(res => {
// console.log(res);
})
//后台处理数据
//方法一(使用内置方法直接获取)
// 处理和解析URL
let urlLib = require('url');
// 解析 URL 字符串并返回 URL 对象
let obj = urlLib.parse(request.url)
// 获取及设置URL的路径(path)部分。pathname 属性包含 URL 的整个路径部分
let ulrname = obj.pathname;
// query 属性是不含开头 ASCII 问号(?)的查询字符串
let getId = obj.query;
//方法二(使用字符串进行分割)
let url = request.url;
url=decodeURI(url);//对接收到的路径进行编码处理
let date = url.substring(2).split('&');
let name= date[0].split('=')[1] ;
post
请求数据
//前端请求数据
fetch(url,{
method:"POST",
body:"username=jack&pwd=123"
}).then(data=>data.json()).then(res=>{
console.log(res);
});
//后台处理数据
let mydata = "";
// 事件监听
request.on('data', chuck => {
//data事件,读取客户端提交的post数据
mydata += chuck;
})
request.on('end', () => {
// console.log(mydata);
mydata = decodeURI(mydata);
setData(mydata, function (obj) {
response.write(JSON.stringify(obj));//将数据响应给前端
response.end();
});
//若end事件触发了,说明data事件执行完了
})
4.总结
通过这些知识的了解,可以写一个前后端互通的小程序。利用模块化的思想对相关的代码进行分离,通过文件系统可以实现数据的存储。利用HTTP模块则能过实现前后端的交互,在前后端交互的时候要注意解决跨域问题。