01-node(基础01).js

服务器黑盒子.png
  1. node.js 是一个开发平台,就像Java开发平台、.Net开发平台、PHP开发平台、Apple开发平台一样。
  • 何为开发平台?有对应的编程语言、有语言运行时、有能实现特定功能的API(SDK:Software Development Kit)
  1. 该平台使用的编程语言是 JavaScript 语言。
  2. node.js 平台是基于 Chrome V8 JavaScript 引擎构建。
  3. 基于 node.js 可以开发控制台程序(命令行程序、CLI程序)、桌面应用程序(GUI)(借助 node-webkit、electron 等框架实现)、Web 应用程序(网站)

PHP开发技术栈: LAMP - Linux Apache MySQL PHP

node.js 全栈开发技术栈: MEAN - MongoDB Express Angular Node.js


node.js 的特点:

1. 事件驱动(当事件被触发时,执行传递过去的回调函数)
2. 非阻塞 I/O 模型(当执行I/O操作时,不会阻塞线程)
3. 单线程
4. 拥有世界最大的开源库生态系统 —— npm。


1.helloworld:
例如文件名为00-helloworld.js

var foo = '你好,世界'
 console.log(foo)

在命令行输入:

  node 00-helloworld.js
node+文件名称.js

注意:不要用node.js来命名或者用中文来命名
在 Node 中,采用 EcmaScript 进行编码
没有 BOM、DOM
和浏览器中的 JavaScript 不一样


读取文件:

浏览器中的 JavaScript 是没有文件操作的能力的, 但是 Node 中的 JavaScript 具有文件操作的能力
fs 是 file-system 的简写,就是文件系统的意思
在 Node 中如果想要进行文件操作,就必须引入 fs 这个核心模块
在 fs 这个核心模块中,就提供了所有的文件操作相关的 API
例如:fs.readFile 就是用来读取文件的

// 1. 使用 require 方法加载 fs 核心模块
   var fs = require('fs')

// 2. 读取文件
 //    第一个参数就是要读取的文件路径
 //    第二个参数是一个回调函数
//        成功:
//          data 数据
 //          error null
  //        失败
 //          data undefined没有数据
//          error 错误对象
  fs.readFile('./data/a.txt', function (error, data) {

  // 在这里就可以通过判断 error 来确认是否有错误发生
 if (error) {
console.log('读取文件失败了')
} else {
console.log(data.toString())
}
 })

写文件:

var fs = require('fs')
 第一个参数:文件路径
 第二个参数:文件内容
第三个参数:回调函数
    error
     成功:
       文件写入成功
      error 是 null
    失败:
        文件写入失败
        error 就是错误对象
fs.writeFile('./data/你好.md', '大家好,给大家介绍一下,我是Node.js', function (error) {

 if (error) {
  console.log('写入失败')
} else {
console.log('写入成功了')
}

http:

// 你可以使用 Node 非常轻松的构建一个 Web 服务器
// 在 Node 中专门提供了一个核心模块:http
// http 这个模块的职责就是帮你创建编写服务器的
// 1. 加载 http 核心模块
var http = require('http')
 // 2. 使用 http.createServer() 方法创建一个 Web 服务器
//    返回一个 Server 实例
 var server = http.createServer()

 // 3. 服务器要干嘛?
//    提供服务:对 数据的服务
//    发请求
//    接收请求
//    处理请求
//    给个反馈(发送响应)
//    注册 request 请求事件
//    当客户端请求过来,就会自动触发服务器的 request 请求事件,然后执行第二个参数:回调处理函数
server.on('request', function () {
 console.log('收到客户端的请求了')
 })
// 4. 绑定端口号,启动服务器
server.listen(3000, function () {
 console.log('服务器启动成功了,可以通过 http://127.0.0.1:3000/ 来  进行访问')
 })

http-res:

var http = require('http')

var server = http.createServer()

 request 请求事件处理函数,需要接收两个参数:
 Request 请求对象
请求对象可以用来获取客户端的一些请求信息,例如请求路径   
Response 响应对象
响应对象可以用来给客户端发送响应消息
 server.on('request', function (request, response) {
 // http://127.0.0.1:3000/ /
 // http://127.0.0.1:3000/a /a
 // http://127.0.0.1:3000/foo/b /foo/b
console.log('收到客户端的请求了,请求路径是:' + request.url)

 response 对象有一个方法:write 可以用来给客户端发送响应数据
 write 可以使用多次,但是最后一定要使用 end 来结束响应,否则客户端会一直等待
response.write('hello')
response.write(' nodejs')

// 告诉客户端,我的话说完了,你可以呈递给用户了
response.end()

 由于现在我们的服务器的能力还非常的弱,无论是什么请求,都只能响应 hello nodejs

 })

 
 server.listen(3000, function () {
 console.log('服务器启动成功了,可以通过 http://127.0.0.1:3000/ 来进行访问')
})

http-url-res:

 var http = require('http')

 // 1. 创建 Server
var server = http.createServer()

// 2. 监听 request 请求事件,设置请求处理函数
  server.on('request', function (req, res) {
   console.log('收到请求了,请求路径是:' + req.url)
  console.log('请求我的客户端的地址是:', req.socket.remoteAddress, 
 req.socket.remotePort)

  // 根据不同的请求路径发送不同的响应结果
 // 1. 获取请求路径
 // req.url 获取到的是端口号之后的那一部分路径
 //    也就是说所有的 url 都是以 / 开头的
  // 2. 判断路径处理响应


 var url = req.url

if (url === '/') {
res.end('index page')
} else if (url === '/login') {
 res.end('login page')
} else if (url === '/products') {
var products = [{
    name: '苹果 X',
    price: 8888
  },
  {
    name: '菠萝 X',
    price: 5000
  },
  {
    name: '小辣椒 X',
    price: 1999
  }
]

// 响应内容只能是二进制数据或者字符串
//  数字
//  对象
//  数组
//  布尔值
res.end(JSON.stringify(products))
} else {
res.end('404 Not Found.')
  }
  })

 // 3. 绑定端口号,启动服务
  server.listen(3000, function () {
 console.log('服务器启动成功,可以访问了。。。')
})

node中的核心模块:

// 用来获取机器信息的
 var os = require('os')
// 用来操作路径的
 var path = require('path')
// 获取当前机器的 CPU 信息
console.log(os.cpus())
 // memory 内存
 console.log(os.totalmem())
// 获取一个路径中的扩展名部分
 // extname extension name
 console.log(path.extname('c:/a/b/c/d/hello.txt'))

Node.js里的模块系统:

require 是一个方法:

它的作用就是用来加载模块的

require在 Node 中,模块有三种:

1.具名的核心模块,例如 fs、http
用户自己编写的文件模块
相对路径必须加 ./
可以省略后缀名
相对路径中的 ./ 不能省略,否则报错

在 Node 中,没有全局作用域,只有模块作用域
外部访问不到内部
  内部也访问不到外部
  默认都是封闭的
a文件:
 var foo = 'aaa'
console.log('a start')
 // function add(x, y) {
    // return x + y
// }
// 推荐:可以省略后缀名
require('./b')
console.log('a end')
console.log('foo 的值是:', foo)
b文件:
console.log('b start')
//console.log(add(10, 20))
   var foo = 'bbb'
 require('./c.js')
 console.log('b end')
c文件:
 console.log('ccc')

运行结果为:

image.png

如果b文件中的 console.log(add(10, 20))运行则会报错。由此说明:

  外部访问不到内部
  内部也访问不到外部
  默认都是封闭的

加载与导出:

既然是模块作用域,那如何让模块与模块之间进行通信
有时候,我们加载文件模块的目的不是为了简简单单的执行里面的代码,更重要是为了使用里面的某个成员

require 方法有两个作用:

1. 加载文件模块并执行里面的代码
2. 拿到被加载文件模块导出的接口对象

在每个文件模块中都提供了一个对象:exports

exports 默认是一个空对象
你要做的就是把所有需要被外部访问的成员挂载到这个 exports 对象中

a文件:

var bExports = require('./b')
 // var fs = require('fs')
 console.log(bExports.foo) //输出hello
 console.log(bExports.add(10, 30)) //输出40但不会输出function add()里的内容
 console.log(bExports.age) //输出18
 bExports.readFile('./a.js')
 fs.readFile('./a.js', function (err, data) {
 if (err) {
console.log('读取文件失败')
  } else {
console.log(data.toString())
}
 })//此处将读取B文件里的源代码

b文件:

   var foo = 'bbb'
 // console.log(exports)
  exports.foo = 'hello'
 exports.add = function (x, y) {
  return x + y
}
function add(x, y) {
 return x - y
 }//此处代码不会被a执行
exports.readFile = function (path, callback) {
  console.log('文件路径:', path)
 }
var age = 18
 exports.age = age

ip地址和端口号:
ip地址和端口号.png

ip 地址用来定位计算机

端口号用来定位具体的应用程序

所有需要联网通信的应用程序都会占用一个端口号

var http = require('http')
var server = http.createServer()
// 2. 监听 request 请求事件,设置请求处理函数
server.on('request', function (req, res) {
  console.log('收到请求了,请求路径是:' + req.url)
  console.log('请求我的客户端的地址是:', req.socket.remoteAddress, 
  req.socket.remotePort)
  res.end('hello nodejs')
})

server.listen(5000, function () {
  console.log('服务器启动成功,可以访问了。。。')
 })
image.png

http-content-type:

在服务端默认发送的数据,其实是 utf8 编码的内容
但是浏览器不知道你是 utf8 编码的内容
浏览器在不知道服务器响应内容的编码的情况下会按照当前操作系统的默认编码去解析
中文操作系统默认是gbk
解决方法就是正确的告诉浏览器我给你发送的内容是什么编码的
http协议中,Content-Type 就是用来告知对方我给你发送的数据内容是什么类型
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
Content-Type常用对照表: http://tool.oschina.net/commons

var http = require('http')
var fs = require('fs')

var server = http.createServer()

server.on('request', function (req, res) {
// / index.html
var url = req.url

if (url === '/') {
// 肯定不这么干
// res.end('<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><h1>首页</h1></body>/html>')

// 我们要发送的还是在文件中的内容
fs.readFile('./resource/index.html', function (err, data) {
  if (err) {
    res.setHeader('Content-Type', 'text/plain; charset=utf-8')
    res.end('文件读取失败,请稍后重试!')
  } else {
    // data 默认是二进制数据,可以通过 .toString 转为咱们能识别的字符串
    // res.end() 支持两种数据类型,一种是二进制,一种是字符串
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.end(data)
  }
})
} else if (url === '/xiaoming') {
// url:统一资源定位符
// 一个 url 最终其实是要对应到一个资源的
fs.readFile('./resource/ab2.jpg', function (err, data) {
  if (err) {
    res.setHeader('Content-Type', 'text/plain; charset=utf-8')
    res.end('文件读取失败,请稍后重试!')
  } else {
    // data 默认是二进制数据,可以通过 .toString 转为咱们能识别的字符串
    // res.end() 支持两种数据类型,一种是二进制,一种是字符串
    // 图片就不需要指定编码了,因为我们常说的编码一般指的是:字符编码
    res.setHeader('Content-Type', 'image/jpeg')
    res.end(data)
  }
})
}
 })
server.listen(3000, function () {
  console.log('Server is running...')
 })

总结:

  • Node 中的 JavaScript

    • EcmaScript

      • 变量

      • 方法

      • 数据类型

      • 内置对象

      • Array

      • Object

      • Date

      • Math

    • 模块系统

      • 在 Node 中没有全局作用域的概念

      • 在 Node 中,只能通过 require 方法来加载执行多个 JavaScript 脚本文件

      • require 加载只能是执行其中的代码,文件与文件之间由于是模块作用域,所以不会有污染的问题

        • 模块完全是封闭的

        • 外部无法访问内部

        • 内部也无法访问外部

      • 模块作用域固然带来了一些好处,可以加载执行多个文件,可以完全避免变量命名冲突污染的问题

      • 但是某些情况下,模块与模块是需要进行通信的

      • 在每个模块中,都提供了一个对象:exports

      • 该对象默认是一个空对象

      • 你要做的就是把需要被外部访问使用的成员手动的挂载到 exports 接口对象中

      • 然后谁来 require 这个模块,谁就可以得到模块内部的 exports 接口对象

      • 还有其它的一些规则,具体后面讲,以及如何在项目中去使用这种编程方式,会通过后面的案例来处理

    • 核心模块

      • 核心模块是由 Node 提供的一个个的具名的模块,它们都有自己特殊的名称标识,例如

        • fs 文件操作模块

        • http 网络服务构建模块

        • os 操作系统信息模块

        • path 路径处理模块

        • 。。。。

      • 所有核心模块在使用的时候都必须手动的先使用 require 方法来加载,然后才可以使用,例如:

        • var fs = require('fs')
  • http

    • require

    • 端口号

      • ip 地址定位计算机

      • 端口号定位具体的应用程序

    • Content-Type

      • 服务器最好把每次响应的数据是什么内容类型都告诉客户端,而且要正确的告诉

      • 不同的资源对应的 Content-Type 是不一样,具体参照:http://tool.oschina.net/commons

      • 对于文本类型的数据,最好都加上编码,目的是为了防止中文解析乱码问题

    • 通过网络发送文件

      • 发送的并不是文件,本质上来讲发送是文件的内容

      • 当浏览器收到服务器响应内容之后,就会根据你的 Content-Type 进行对应的解析处理

  • 模块系统

  • Node 中的其它的核心模块

  • 做一个小管理系统:

    • CRUD
  • Express Web 开发框架

    • npm install express
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • 作者:马龄阳efe.baidu.com/blog/nodejs-module-analyze/ Node.js 的...
    grain先森阅读 1,129评论 2 17
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    w_zhuan阅读 3,612评论 2 41
  • 个人入门学习用笔记、不过多作为参考依据。如有错误欢迎斧正 目录 简书好像不支持锚点、复制搜索(反正也是写给我自己看...
    kirito_song阅读 2,461评论 1 37
  • Node.js第一天 1. 初识Node.js 1.1 Node.js是什么 Node.js® is a Java...
    再见天才阅读 4,727评论 1 24
  • Node.js Stream(流) Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对h...
    FTOLsXD阅读 604评论 0 2