nodejs是运行在服务端的JavaScript;一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
不管是什么类型的模块,nodejs都是通过 requier(url) 引入加载模块 (nodejs 使用的 CommonJS规范)
// app.js
function fun(){}
let obj = {}
// 真正暴露出去的是 exports 对象,
module.exports = {
fun,
obj
}
// index.js
// 暴露的也是 exports对象, 给对象exports对象添加属性并赋值
exports.fun = function(){}
exports.str = 'hello'
所有的模块都是通过 require(url) 引入模块
// 引入内置模块:
const http = require('http') // 引入内置模块, 直接写模块名字
// 引入自定义模块
const app = require('./app.js') // 特别注意路径,同级目录需要添加 前缀 ./
// 引入第三方模块 mysql
// 在使用第三方模块之前,都要初始化项目 npm init -y 生成 package.json 文件
// npm install mysql --save // 下载安装 安装的文件的路径和入口文件的关系
// const mysql = require('mysql')
通过内置模块http搭建服务器
const http = requrie('http');
// 链式写法
http.createServer((request, response) => {
// request : 客户端向服务器请求传递的数据 简写req
// response : 服务器向客户端响应的数据 简写res
// 设置响应头 text/html text/plain
res.writeHead(200, {"Content-type":"text/html;charset=utf-8"})
// 响应数据
response.write('hello world') // 响应的数据; 可以多个
response.end() // 终止响应 end() 可以接受参数的, 参数依然是响应的数据; 只能有一个; 响应结束后 不能再进行任何相关操作
}).listen(3000, () => {
console.log('服务是否成功开启')
})
// 分开写的方式
const server = http.createServer((req, res) => {
res.end('hello')
})
server.listen(3000, () => {
})
引入fs模块
const fs = require('fs')
fs.readFile(url, (err, result) => {
// url 文件的地址
// err 读取失败的信息 null : 读取成功
// result 读取的结果(数据) 默认是一个buffer类型 通过 toString() 转换
})
// 如果文件不存在则创建 , 文件存在则写入并覆盖原文本内容
fs.writeFile(url, content, () => {
// url 文件的地址
// content 写入的文件内容
// callback 回调函数 写入失败的信息
})
// 如果文件不存在则创建 , 文件存在则追加内容
fs.appendFile(url, content, () => {
// url 文件的地址
// content 追加的文件内容
// callback 回调函数 写入失败的信息
})
fs.unlink(url, () => {
// url 文件的地址
// callback 回调函数 删除失败的信息
})
fs.rename(oldUrl, newName, () => {
// oldUrl 原文本的地址 源文件名字
// newName 重新命名文件名 新名字
// callback 回调函数 命名失败的信息
})
const read = fs.createReadStream('读取的文件地址');
// 监听读取的数据改变
let body = '' // 接受读取的数据
read.on('data', (chunk) => {
body += chunk;
})
// 监听数据读取结束
read.on('end', () => {
console.log('数据读取完成')
})
// 监听 读取失败的信息
read.on('error', () => {
console.log('数据读取失败')
})
// fs.WriteStream 类 继承自 <stream.Writable>
const writeStream = fs.createWriteStream('写入的文件地址');
// 创建写入的数据
let result = 'hello world';
// 写入数据 writable.write() 写入数据到流,并在数据被完全处理之后调用 callback。 如果发生错误,则 callback 可能被调用也可能不被调用。 为了可靠地检测错误,可以为 'error' 事件添加监听器。 callback 会在触发 'error' 之前被异步地调用。
// writable.write(chunk[, encoding][, callback])
writeStream.write(result);
// 写入完成 调用 writable.end() 表明已没有数据要被写入可写流。 可选的 chunk 和 encoding 参数可以在关闭流之前再写入一块数据。 如果传入了 callback 函数,则会做为监听器添加到 'finish' 事件和 'error' 事件。
// writable.end(chunk[, encoding][, callback])
writeStream.end(); //
// 监听 finish 事件和 error 事件
// 创建一个读流
const read = fs.createReadStream('读取的文件地址');
// 创建写流
const writeStream = fs.createWriteStream('写入的文件地址');
// 通过管道流实现 数据复制
read.pipe(writeStream)
对路径进行相关操作
path.extname() 方法会返回 path 的扩展名,即 path 的最后一部分中从最后一次出现 .(句点)字符直到字符串结束。 如果在 path 的最后一部分中没有 .,或者如果 path 的基本名称(参见 path.basename())除了第一个字符以外没有 .,则返回空字符串
const path = require('path');
let str = 'index.html';
let res = path.extname(str);
path.join() 方法会将所有给定的 path 片段连接到一起(使用平台特定的分隔符作为定界符),然后规范化生成的路径
const path = require('path');
let res = path.join('/foo', '/baz', 'a.html')
// 路径参数不符合规则,则报错 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of Array
let res = path.join('./foo', {}, "index.css")
path.normalize() 方法规范化给定的 path,解析 ‘…’ 和 ‘.’ 片段。
当找到多个连续的路径段分隔字符时(例如 POSIX 上的 /、Windows 上的 \ 或 /),则它们将被替换为单个平台特定的路径段分隔符(POSIX 上的 /、Windows 上的 \)。 尾部的分隔符会保留。
const path = require('path');
let res = path.normalize('www.baidu.com')
let res = path.normalize('https:///www.baidu.com//index.html') // https:\www.baidu.com\index.html
let res = path.normalize('https:///www.baidu.com/../index.html') // https:\index.html
console.log(__dirname) // 文件所在的目录(不包含文件本身)
console.log(__filename) // 文件所在的目录(包含文件本身) (文件详细的路径)
处理+ 解析url
const url = require('url');
let path = 'https://baike.baidu.com/小说/brief#4';
// 把url字符串转换为url对象
let res = url.parse(path);
// 解析 query查询数据转换为对象 , 需要借助第二个参数 url.parse(path, true);
let path = 'https://baike.baidu.com/?keyword=小说&brief#4';
let res = url.parse(path, true).query;
querystring.parse() 方法将 URL 查询字符串 str 解析为键值对的集合。
const querystring = require('querystring');
// user=张三&pwd=123456 ===> {user:张三, pwd:123456}
let body = querystring.parse(data)
// 自定义模块
function getType(extname) {
let type = ''
switch (extname) {
case '.html':
type = 'text/html';
break;
case '.css':
type = 'text/css';
break;
case '.js':
type = 'application/javascript';
break;
case '.jpg':
type = 'image/jpeg';
break;
default:
type = 'text/plain'
}
return type;
}
module.exports = {
getType
}
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
// const mime = require('mime'); // 安装第三方插件 mime 使用 mime.getType(extname)
const { getType } = require('./mime'); // 自定义模块
http.createServer(function (request, response) {
// 对请求的资源路径进行解析 pathname 就是资源文件名
let pathname = url.parse(request.url).pathname;
// 设置默认加载的页面 (index.html)
pathname = pathname === '/' ? '/index.html' : pathname;
// 获取文件的扩展名
let extname = path.extname(pathname);
// 根据扩展名 获取文件对应的MIME 类型
let type = getType(extname);
// 开始读取静态资源文件
fs.readFile('资源所在的文件路径' + pathname, (err, result) => {
if(err){
response.writeHead(404, {'Content-type':'text/html;charset=utf-8'});
response.end('资源加载失败')
}else{
response.writeHead(200, {'Content-type':`${type};charset=utf-8`})
response.write(result);
response.end();
}
})
}).listen(3000, () => {
console.log('Server running at http://127.0.0.1:8081/');
});
const http = require('http');
const url = require('url');
http.createServer(function (request, response) {
let query = url.parse(request.url, true).query
console.log(query);
response.writeHead(200, { 'Content-Type': 'text/plain;charset=utf-8' });
if (query.user == 'admin' && query.pwd == '123') {
response.end('Hello World');
} else {
response.end('用户名或密码错误');
}
}).listen(3000, () => {
console.log('Server running at http://127.0.0.1:8081/');
});
POST 请求的内容全部的都在请求体中,http.ServerRequest 并没有一个属性内容为请求体,原因是等待请求体传输可能是一件耗时的工作。
比如上传文件,而很多时候我们可能并不需要理会请求体的内容,恶意的POST请求会大大消耗服务器的资源,所以 node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做
const http = require('http');
const querystring = require('querystring');
http.createServer(function (request, response) {
// 声明一个变量 body 用来接收传递的数据
let body = '';
// 监听data事件, - 当有数据可读时触发。
request.on('data', (chunk) => {
body += chunk;
})
// 监听 end 事件, 没有更多的数据可读时触发。 证明数据传递结束了(数据传输完成)
request.on('end', () => {
body = querystring.parse(body);
console.log(body);
})
response.writeHead(200, { 'Content-Type': 'text/plain;charset=utf-8' });
response.end('ehello')
}).listen(3000, () => {
console.log('Server running at http://127.0.0.1:8081/');
});
const http = require('http');
const url = require('url');
http.createServer((req, res) => {
// 处理跨域问题
res.setHeader('Access-Control-Allow-Origin', "*");
// 如果前端传递了请求的数据, 需要处理 request.url 获取查询字段query
let query = url.parse(req.url, true).query
// 根据用户传递的数据进行相应的操作 : 增删改查 操作数据库
if(){
// 查询数据
}else if(){
// 添加数据
}
res.write(data) // data 就是服务器向客户端响应的数据 这个数据是字符串类型(json字符串)
res.end();
})
$.ajax({
url:'服务器的地址';
type:'get',
data:{} // 请求传递的数据
dataType:'json', // 返回的数据类型
success:function(data){
// data 请求成功的数据
// 根据返回的数据 判断操作时成功还是失败 然后进行下一步操作
}
})