前言

  经过了一周半的时间学习Vue,已经基本掌握Vue的用法。
  最近也花了将近一周的时间简单开发了一个 SPA ,感觉实践之后才发觉自己掌握还很粗浅。
  不过没关系,慢慢练习,自然就不断精进了。
  因为 SPA 还需要后台系统,因此开发到中途,我将UI设计交给了舍友,继续来肝 Nodejs 做服务端的教程
  这次依旧是在B站找了个教程。

  因为我之前已经接触过 PHP 也大致了解服务端的处理,因此我看得速度很快,基本上就挑些重点记录下来。
  本期记录了教程 1 - 25 集 Day1 —— Day2

基础操作

hello,world

hello,world

  node.js 第一行代码
  其实非常好理解,就像安装python编译器之后,跑代码是一样的。
  node.js的特点就是让JavaScript跳出了浏览器的束缚,有更加自由的能力。

没有浏览器的 DOM 和 BOM

hello,world

  毕竟node.js已经跳过了浏览器来执行,也就没有了 window 和 document 的全局变量。

文件读取

文件读取
文件读取
文件读取

  通过输入node的命令就可以实现文件读取。
  需要注意的是 require 是 node.js 添加的功能
  如果在浏览器上执行 require 会报错

文件写入 以及 错误处理

文件写入

  文件写入也很简单,可以参照文件读取

错误处理

  Nodejs执行会在回调函数传入错误信息
  需要调用错误信息才能将错误反馈
  如果没有错误信息 回调函数额 error 参数获取的是null,通过这个值就可以进行错误处理。

搭建服务器

搭建服务器
搭建服务器
搭建服务器

  node.js 搭建服务器也非常简单,如上图代码。
  通过listen进行监听,打开网页,就可以request的函数,在命令行中进行输出。

服务器响应处理

服务器响应处理

  通过上面代码就可以知道用户访问的网页地址,并且可以通过 write 输出信息到页面上。

node 中的模块加载

模块加载

  模块加载和 python 基本一样,只不过了换成 require 并且支持路径加载
  不过 node 加载模块之后是不会暴露模块中的东西,需要用过 exports 来讲模块中对应的内容传递出来。

通信原理

通信端口
通信端口

  程序通信需要有唯一地址来避免通信干扰,一般IP地址的端口就是用来区分不同程序的通信。
  通信两方都会开启端口进行信息互通,不仅仅是服务器暴露通信端口,浏览器也会调用客户端的端口来去和服务器通信,发送请求。

通信端口

  不过用户不用担心端口的问题,浏览器自动调用系统中的资源。
  端口号可以选用的数值为 0 - 65536

服务器 header

中文乱码

  因为浏览器不知道服务器返回数据的编码格式,因此会默认调用系统的编码。
  因此指定返回头文件就可以解决问题。

请求头

  通过请求可以让浏览器正确处理服务器返回的内容。

地址处理

返回数据

  通过地址处理以及头信息的正确返回,可以让任意地址指向不同的资源。

Content-Type

分号处理

分号

  在 standard JavaScript 权威规范中,推荐代码不添加分号
  但是在上述的符号作为行首的时候,不加分号会导致代码出问题,留个心眼就好。

客户端 & 服务端

分号

  客户端和服务端的异同
  服务端之所以可以实现SEO优化,是因为搜索引擎的爬虫爬取信息是不会执行 js 脚本的(节省资源)
  因此只有纯文本的信息会被抓取。

资源请求

资源请求

  当浏览器识别到网页的内容之后,会一次解析HTML中的相关属性标签然后发送请求

服务端处理请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// app application 应用程序
// 把当前模块所有的依赖项都声明再文件模块最上面
// 为了让目录结构保持统一清晰,所以我们约定,把所有的 HTML 文件都放到 views(视图) 目录中
// 我们为了方便的统一处理这些静态资源,所以我们约定把所有的静态资源都存放在 public 目录中
// 哪些资源能被用户访问,哪些资源不能被用户访问,我现在可以通过代码来进行非常灵活的控制
// / index.html
// /public 整个 public 目录中的资源都允许被访问
// 前后端融会贯通了,为所欲为

var http = require('http')
var fs = require('fs')
var url = require('url')
var template = require('art-template')

var comments = [
{
name: '张三',
message: '今天天气不错!',
dateTime: '2015-10-16'
},
{
name: '张三2',
message: '今天天气不错!',
dateTime: '2015-10-16'
},
]

// /pinglun?name=的撒的撒&message=的撒的撒的撒
// 对于这种表单提交的请求路径,由于其中具有用户动态填写的内容
// 所以你不可能通过去判断完整的 url 路径来处理这个请求
//
// 结论:对于我们来讲,其实只需要判定,如果你的请求路径是 /pinglun 的时候,那我就认为你提交表单的请求过来了

http
.createServer(function (req, res) { // 简写方式,该函数会直接被注册为 server 的 request 请求事件处理函数
// 使用 url.parse 方法将路径解析为一个方便操作的对象,第二个参数为 true 表示直接将查询字符串转为一个对象(通过 query 属性来访问)
var parseObj = url.parse(req.url, true)

// 单独获取不包含查询字符串的路径部分(该路径不包含 ? 之后的内容)
var pathname = parseObj.pathname

if (pathname === '/') {
fs.readFile('./views/index.html', function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
var htmlStr = template.render(data.toString(), {
comments: comments
})
res.end(htmlStr)
})
} else if (pathname === '/post') {
// 其它的都处理成 404 找不到
fs.readFile('./views/post.html', function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
res.end(data)
})
} else if (pathname.indexOf('/public/') === 0) {
// /public/css/main.css
// /public/js/main.js
// /public/lib/jquery.js
// 统一处理:
// 如果请求路径是以 /public/ 开头的,则我认为你要获取 public 中的某个资源
// 所以我们就直接可以把请求路径当作文件路径来直接进行读取
fs.readFile('.' + pathname, function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
res.end(data)
})
} else if (pathname === '/pinglun') {
// 注意:这个时候无论 /pinglun?xxx 之后是什么,我都不用担心了,因为我的 pathname 是不包含 ? 之后的那个路径
// 一次请求对应一次响应,响应结束这次请求也就结束了
// res.end(JSON.stringify(parseObj.query))

// 我们已经使用 url 模块的 parse 方法把请求路径中的查询字符串给解析成一个对象了
// 所以接下来要做的就是:
// 1. 获取表单提交的数据 parseObj.query
// 2. 将当前时间日期添加到数据对象中,然后存储到数组中
// 3. 让用户重定向跳转到首页 /
// 当用户重新请求 / 的时候,我数组中的数据已经发生变化了,所以用户看到的页面也就变了
var comment = parseObj.query
comment.dateTime = '2017-11-2 17:11:22'
comments.unshift(comment)
// 服务端这个时候已经把数据存储好了,接下来就是让用户重新请求 / 首页,就可以看到最新的留言内容了

// 如何通过服务器让客户端重定向?
// 1. 状态码设置为 302 临时重定向
// statusCode
// 2. 在响应头中通过 Location 告诉客户端往哪儿重定向
// setHeader
// 如果客户端发现收到服务器的响应的状态码是 302 就会自动去响应头中找 Location ,然后对该地址发起新的请求
// 所以你就能看到客户端自动跳转了
res.statusCode = 302
res.setHeader('Location', '/')
res.end()
} else {
// 其它的都处理成 404 找不到
fs.readFile('./views/404.html', function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
res.end(data)
})
}
})
.listen(3000, function () {
console.log('running...')
})

// Node 不适合从来没有接触过服务端的人学习
// 如果想要真正的学号服务端,还是老牌的 Java、PHP 这些平台
// Node 不是特别适合入门服务端,但不代表 Node 不强大
// Node 很厉害,具有经验的人可以玩儿的非常的牛
// 不适合新手的原因就在于比较偏底层、而且太灵活
// Java、PHP 好入门的原因就在于:这些平台屏蔽了一些底层
// res.redirect('重定向')

  通过将数据发送到服务端对应的地址,就可以通过 nodejs 来写服务端的请求
  确实 Nodejs 很灵活,写起来也比起 LAMP 或者 LNMP 要复杂一些。
  不过理解了背后的原理制作起来也没有那么困难。