node.js
介绍
是什么
node.js是一个开发平台,有对应的编程语言,在语言运行时,有实现特有功能的API
该平台使用的编程语言为JavaScript语言
node.js 平台是基于 Chrome V8 JavaScript 引擎构建。
基于 node.js 可以开发控制台程序(命令行程序、CLI程序)、桌面应用程序(GUI)(借助 node-webkit、electron 等框架实现)、Web 应用程序(网站)
特点:
事件驱动(当事件被触发时,执行传递过去的回调函数)
非阻塞 I/O 模型(当执行I/O操作时,不会阻塞线程)
单线程
拥有世界最大的开源库生态系统 —— npm。
node.js网站
官方网站:https://nodejs.org/
中文网站:http://nodejs.cn/
中文社区:https://cnodejs.org/
API:http://nodejs.cn/api/
第三方npm:https://www.npmjs.com/
nodejs开发web应用程序和PHP、java、ASP.Net等传统模式开发的区别
传统模式:
必须要有web容器
在web容器里面写具体的动态页面
nodejs:
没有web容器,本身就是一个http服务器
每个请求后都必须自己写代码去处理,如果不写代码处理这个请求就不会处理
REPL
REPL全称: Read-Eval-Print-Loop(交互式解释器)
R 读取 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。
E 执行 执行输入的数据结构
P 打印 输出结果
L 循环 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
在REPL中编写程序
类似于浏览器开发人员工具中的控制台功能
直接在控制台输入node命令进入REPL环境
退出
输入.exit
按住Ctrl键不要放开, 然后按两下c键
JavaScript 文件名命名规则
不要用中文
不要包含空格
不要出现node关键字
建议以 '-' 分割单词
文件操作
写文件
var fs = require ( 'fs' ) ;
var msg = 'hello,world,你好世界!' ;
fs. writeFile ( './hello.txt' , msg, 'utf-8' , function ( err ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
console. log ( 'ok' ) ;
}
} ) ;
读文件
var fs = require ( 'fs' ) ;
fs. readFile ( './hello.txt' , function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
console. log ( data. toString ( "utf-8" ) ) ;
}
} ) ;
fs. readFile ( './hello.txt' , 'utf-8' , function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
console. log ( data) ;
}
} ) ;
var path = require ( 'path' ) ;
var filename = path. join ( __dirname, 'hello.txt' ) ;
fs. readFile ( filename, 'utf-8' , function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
console. log ( data) ;
}
} ) ;
创建文件目录
var fs = require ( 'fs' ) ;
fs. mkdir ( 'text-mkdir' , function ( err ) {
if ( err) {
console. log ( '创建目录失败,详细信息如下:' ) ;
console. log ( err) ;
} else {
console. log ( '目录创建成功' ) ;
}
} )
编写http服务程序
var http = require ( 'http' ) ;
var server = http. createServer ( ) ;
server. on ( 'request' , function ( req, res ) {
res. setHeader ( 'Content-Type' , 'text/plain; charset=utf-8' ) ;
res. write ( 'hello world 你好世界' ) ;
res. end ( ) ;
} ) ;
server. listen ( 80 , function ( ) {
console. log ( '服务器启动了,请访问...' )
} )
var http = require ( 'http' ) ;
http. createServer ( function ( req, res ) {
res. setHeader ( 'Content-Type' , 'text/plain; charset=utf-8' ) ;
if ( req. url === '/' || req. url === '/index' ) {
res. end ( 'hello index' ) ;
} else if ( req. url === '/login' ) {
res. end ( 'hello login' ) ;
} else {
res. end ( '404,not Found 客户端错误' ) ;
}
} ) . listen ( 80 , function ( ) {
console. log ( '服务器启动了,请访问...' )
} )
var path = require ( 'path' ) ;
var fs = require ( 'fs' ) ;
var http = require ( 'http' ) ;
http. createServer ( function ( req, res ) {
if ( req. url === '/' || req. url === '/index' ) {
var filename = path. join ( __dirname, 'https' , 'index.html' ) ;
fs. readFile ( filename, function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
res. end ( data) ;
}
} ) ;
} else if ( req. url === '/images/index.png' ) {
var filename = path. join ( __dirname, 'images' , 'index.png' ) ;
fs. readFile ( filename, function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
res. setHeader ( 'Content-Type' , 'image/png' ) ;
res. end ( data) ;
}
} ) ;
} else if ( req. url === '/css/index.css' ) {
var filename = path. join ( __dirname, 'css' , 'index.css' ) ;
fs. readFile ( filename, function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
res. setHeader ( 'Content-Type' , 'text/css' ) ;
res. end ( data) ;
}
} ) ;
} else if ( req. url === '/login' ) {
var filename = path. join ( __dirname, 'https' , 'login.html' ) ;
fs. readFile ( filename, function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
res. end ( data) ;
}
} ) ;
} else {
var filename = path. join ( __dirname, 'https' , '404.html' ) ;
fs. readFile ( filename, function ( err, data ) {
if ( err) {
console. log ( '写文件错误' + err) ;
} else {
res. end ( data) ;
}
} ) ;
}
} ) . listen ( 80 , function ( ) {
console. log ( '服务器启动了,请访问...' )
} )
模拟Apache
var path = require ( 'path' ) ;
var fs = require ( 'fs' ) ;
var http = require ( 'http' ) ;
var mime = require ( 'mime' ) ;
http. createServer ( function ( req, res ) {
var filrname = path. join ( __dirname, 'public' , req. url) ;
fs. readFile ( filrname, function ( err, data ) {
if ( err) {
var filename = path. join ( __dirname, 'https' , '404.html' ) ;
fs. readFile ( filename, function ( err, data ) {
res. end ( data) ;
} ) ;
} else {
res. setHeader ( 'Content-Type' , mime. getType ( filrname) ) ;
res. end ( data) ;
}
} )
} ) . listen ( 80 , function ( ) {
console. log ( '服务器启动了,请访问...' ) ;
} )
request
对应http. IncomingMessage 类
服务器解析用户提交的 http 请求报文,将结果解析到 request 对象中
凡是要获取和用户请求相关的数据都可以通过 request 对象获取
常用对象
console. log ( req. headers) ;
console. log ( req. rawHeaders) ;
console. log ( req. httpVersion) ;
console. log ( req. method) ;
console. log ( req. url) ;
response
对应http. ServerResponse 类
在服务器端用来向用户做出响应的对象。
凡是需要向用户(客户端)响应的操作,都需要通过 response 对象来进行。
常用对象
response. writeHead ( 404 , 'Not found' , {
'Content-Length' : Buffer. byteLength ( body) ,
'Content-Type' : 'text/plain'
} )
res. write ( 'hello world 你好世界' ) ;
res. end ( 'over' ) ;
常见错误号
EACCES ( Permission denied)
An attempt was made to access a file in a way forbidden by its file access permissions.
访问被拒绝
EADDRINUSE ( Address already in use)
An attempt to bind a server ( net, http, or https) to a local address failed due to another server on the local system already occupying that address.
地址正在被使用(比如:端口号备占用)
EEXIST ( File exists)
An existing file was the target of an operation that required that the target not exist.
文件已经存在
EISDIR ( Is a directory)
An operation expected a file, but the given pathname was a directory.
给定的路径是目录
ENOENT ( No such file or directory)
Commonly raised by fs operations to indicate that a component of the specified pathname does not exist -- no entity ( file or directory) could be found by the given path.
文件 或 目录不存在
ENOTDIR ( Not a directory)
A component of the given pathname existed, but was not a directory as expected. Commonly raised by fs. readdir.
给定的路径不是目录
npm
查看当前版本 npm -v
更新npm npm install nap@latest -g
使用
在https://www.npmjs.com/网站中找到需要安装的包
在项目根目录下执行npm install 包名称 安装
在nodejs代码中通过requrie(包名),加载模块
创建一个package.json文件
一步步生成 npm init
一次性生成 npm init -y
卸载包 npm uninstall 包名
package.json 文件
package.json 文件的作用?
1. package.json 文件是一个包说明文件(项目描述文件),用来管理组织一个包(一个项目)
2. package.json 文件是一个 json 格式的文件
3. 位于当前项目的根目录下
元数据
package.json 文件中常见的项有哪些?
name 包的名字
version 包的版本
description 包描述
author 包的作者
main 包的入口js文件,从main字段这里指定的那个js文件开始执行
dependencies当前包依赖的其他包
如何创建一个 package.json 文件
1. 通过 npm init 命令 或者 npm init -y 或 npm init -yes 命令
2. 手动创建一个
注意
1. 通过 npm init -y 或 npm init -yes 创建 package.json 文件时,执行命令所在的目录接名称中不能包含大写字母
2. package.json 文件中,项目名称本身不能包含大写字母
3. npm 更新新版本后,项目所在的文件夹如果包含中文等特殊字符,创建的时候不会提示一步一步的输入,直接报错。
require
1. 看 require ( ) 加载模块时传入的参数是否以 './' 或 '../' 或 '/' 等等这样的路径方式开头(相对路径或绝对路径都可以)
2. 是,那么会按照传入的路径直接去查询对应的模块。
传入的是否为具体的文件名
require ( './test.js' ) 是具体的文件名
直接根据给定的路径去加载模块,找到了加载成功,找不到加载失败
require ( './test' ) ; 不是具体的文件名、
第一步:根据给定的路径,依次添加文件后缀 . js、. json、. node进行匹配,如果找不到匹配执行第二步
第二步:查找是否有 test 目录(尝试找 test 包)
找不到:加载失败
找到了:依次在 test 目录下查找 package . json 文件(找到该文件后尝试找 main字段中的入口文件)、index. js、index. json、index. node,找不到则加载失败
3. 不是,那么就认为传入的是 "模块名称" (比如:require ( 'http' ) 、require ( 'mime' ) )
是核心模块:直接加载核心模块
不是核心模块:依次递归查找 node_modules 目录中是否有相应的包
从当前目录开始,依次递归查找所有父目录下的 node_modules 目录中是否包含相应的包
如果查找完毕磁盘根目录依然没有则加载失败
打印输入 module. paths 查看
require ( './index2.js' )
index. js/ index. json/ index. node) - > 加载失败
require ( 'ndex2' )
require 加载模块注意点
1. 所有模块第一次加载完毕后都会有 缓存,二次加载直接读取缓存,避免了二次开销,因为有缓存,所以模块中的代码只在第一次加载的时候执行一次
2. 每次加载模块的时候都优先从缓存中加载,缓存中没有的情况下才会按照 node. js 加载模块的规则去查找
3. 核心模块在 Node. js 源码编译的时候,都已经编译为二进制执行文件,所以加载速度较快(核心模块加载的优先级仅次于 缓存加载)
4. 核心模块都保存在 lib 目录下
5. 试图加载一个和 核心模块 同名的 自定义模块(第三方模块)是不会成功的,自定义模块要么名字不要与核心模块同名,要么使用路径的方式加载
6. 核心模块 只能通过 模块名称 来加载
(错误示例:require ( './http' ) ; 这样是无法加载 核心模块http的 )
7. require ( ) 加载模块使用 . / 相对路径时,相对路径是相对当前模块,不受执行 node 命令的路径影响
8. 建议加载文件模块的时候始终添加文件后缀名,不要省略。