一、HTTP协议
1.1 HTTP简介
HTTP: Hypertext Transfer Protocol 超文本传输协议
协议: 协商出来的条例。双方(多方)都必须遵守。
双方: 浏览器和服务器。
浏览器: 一个应用程序,用于渲染服务器上的内容给用户看到。
服务器: 一个应用程序,浏览器看到的内容本质上都在服务器上。
1.2 HTTP组成部分
一共分为四个组成部分: 请求首行、 请求头、 请求空行、 请求正文
请求首行:
请求头:
请求空行: 略
因为空行,就是一个空格 它的作用是为了区分请求头和请求正文。
请求正文:
如果是get请求,它没有请求正文。
如果是post请求,它有请求正文。
1.3 请求方式
在HTTP协议设计之初,对每一次的请求的目的进行了区分。 于是就给每一个请求设定了一个叫做“method”key。 它用于确定本次请求是:“要从服务器上拿东西”还是“往服务器上放东西”
拿东西: GET
放东西: POST
还有一系列其他请求: PUT、DELETE等。
1.4 URL
URL: 统一资源定位符
它使用来定位网上的资源。
例如: https://www.baidu.com/
https://www.baidu.com/index.html
其实,这两个URL指向的是同一个资源。
再比如: https://www.icketang.com/
https://www.icketang.com/index.html
完整的URL:
http://www.icketang.com/a/b/c.html?username=zhangsan#aaa
URL的组成部分:
协议: https
主机名: www.icketang.com
端口: 80
主机: 主机名+端口
path:/a/b/c.html?username=zhangsan
pathName: /a/b/c.html
query: username=zhangsan
hash: #aaa
其中,端口、query、hash可省略
二、小故事
从前,有一个人,他有一个很漂亮的网页。(当时还没有网站,互联网刚刚兴起)别人想要看,使用U盘拷贝。但是,随着网页越来越漂亮,拷贝的人越来越多。这个人每天就不用干别的了。而且,来拷贝的人也耽误事。 于是就有人说: “哥们,你把网页,放到网上” 于是,网站就诞生了。
网站有了,怎么访问? 于是,URL就诞生了。 一开始的URL是ip+端口的形式。机器容器理解,但是人不容易理解,于是就诞生了一个管理组织,专门管理ip+端口与域名的转换。于是DNS就诞生了,DNS就是专门负责将域名转换成ip的服务器。全球一共13台。整个亚洲只有一台。
访问能够访问了,但是传递数据又成了一个问题,凭什么服务器发送给浏览器的内容能够保持一致。于是HTTP协议就诞生了。
三、NodeJS
3.1 官网
3.2 简单的NodeJS代码
代码:
运行:
1 切换到该目录下
2 使用node命令运行对应的文件
3.3 搭建Node服务器
搭建Node服务器要借助内置模块 HTTP
代码:
1 var http = require(“http”);
2 var server = http.createServer();
3 server.listen(3000);
运行:
访问:
3.4 Node服务器处理请求
原生的node服务器处理请求通过createServer接受的事件响应函数来处理。
1 // 1 引入http模块
2 var http = require(“http”);
3 // 2 搭建服务器
4 var server = http.createServer(function() {
5 console.log(“前端有请求过来了”);
6 });
7 // 3 监听端口号
8 server.listen(3000);
此时,你无论如何访问,后端都会,也只会输出“前端有请求过来了”。
3.5前后端请求对象
1 // 1 引入http模块
2 var http = require("http");
3 // 2 搭建服务器
4 var server = http.createServer(function(request, response) {
5 // 该程序是一个服务器 服务器必须能够接受前端请求 并返回数据
6 // 这些前端请求 通过本函数的第一个参数表示 我们一般把它的名称定为request 或者 req
7
8 console.log(request.method); // 本次的请求方式 get 还是post 或者是其他请求方式
9 console.log(request.connection.remoteAddress); // 本次前端的ip地址
10
11
12 // 同样的, 后端响应对象 通过本函数的第二个参数表示 我们一般把它定为response 或者 res
13 // 设置编码
14 response.setHeader("content-type", "text/plain;charset=utf-8");
15 // end方法表示结束并返回内容 end方法只可以接受2种参数 第一种是buffer 第二种是字符串
16 response.end("你好,我是一个node服务器");
17 });
18 // 3 监听端口号
19 server.listen(3000, "192.168.2.187");
3.6 NodeJS特点
NodeJS有3大特点: 单线程、 非阻塞I/O、 事件驱动
单线程:指的就是在执行任务的时候只有一个线程在执行。(只有一个任务队列)
非阻塞I/O:
首先要明白什么叫做I/O。
I:input O: output
从硬盘内存读取内容 叫做input
从内存向硬盘输出内容 叫做output
其次,得知道为什么会阻塞。 阻塞的意思是:在内存和硬盘有数据传输的时候,内存运行速度快、硬盘转速慢、此时如果线程在等待数据传输完毕,那么就叫做阻塞I/O。 如果线程不等待那么叫做非阻塞I/O。
事件驱动: 其实事件驱动和非阻塞I/O是连在一起的。 更简单的理解方式: 事件驱动了程序的往下运行。
3.7 详解
有一个诊所(服务器),里面有一个医生(线程)。
有N个护士(内存), 有一个仓库(硬盘)。
有10个病人(请求)。
医生早上开门,第一个病人进来,医生给他诊断,诊断完毕,要开药方,抓药,此时护士去抓药去了。这个护士去抓药的过程就是I/O。医生后续要等护士回来,给病人开医嘱。如果医生等着护士回来,这就叫做阻塞I/O。那么开医嘱这个任务就能够正常执行。 如果医生不等待护士回来,而是去给第二个病人看病,这就叫做非阻塞I/O。 但是因为没等护士回来,所以开医嘱这个行为将无法执行,没关系,护士回来之后,会触发一个事件,这个事件驱动了医生去开医嘱。
Node的运行机制是诊所运行机制。
不管来多少人,就一个线程在支撑。 数量不到一定的级数,那么毫无压力。 超过一定的级数,压力不大,但是依旧得排队。
其它服务器语言的运行机制是大医院的运行机制。 不管来多少人,一人一个线程。 数量达不到一定的级数,比较浪费,达到一定的级数,可以稳定支撑,但是依旧浪费。
四、 Node模块化
4.1 分类
Node是模块化开发,遵循CommonJS规范。
一个JS文件就是一个模块。
NodeJS的模块可以分为两大类。
第一类: 内置核心模块
以上这些都是内置核心模块。
第二类属于第三方模块
自定义的模块,别人写好的模块都属于第三方模块。
这些第三方模块,可以上传到npm上。
NPM:Node Package Manager
4.2 引入规则
像Seajs一样,引入使用require函数。
该函数如果引入核心模块,那么直接使用核心模块的名称字符串即可。
例如:
1 var http = require(“http”);
如果引入的是第三方模块,那么需要使用相对路径写法。
1 var a = require("./a"); // 注意: ./ 与 不写 都表示相对路径 但是一旦不写 此时将会是 require(“a”); 那么问题来了,这到底是一个核心模块 还是一个第三方模块? 有歧义,所以必须使用./写法
4.3 node_modules文件夹
node提供了一个文件夹, 叫做node_modules。
该文件夹可以随意创建。
特点: 在该文件夹内的模块,可以像引入核心模块那样引入。
五、 URL模块
5.1 功能
URL模块,用于解析URL字符串。
类比:
JSON: 能够将JSON字符串 转为 JSON对象 也能够将JSON对象 转为JSON字符串
URL: 能够将URL字符串 转为URL对象 也能够将URL对象 转为URL字符串
5.2 解析URL字符串
URL.parse(url_str, boolean);
url_str: 被解析的字符串
boolean: 布尔值 当为true 时 会将query部分解析成对象
demo:
1 // 定义一个完整的URL
2 var str_url = "http://www.icketang.com/index.html?a=1#aaaa";
3
4 // 引入URL模块
5 var url = require("url");
6
7 // 将str_url这个字符串 转化成url对象
8 var url_obj = url.parse(str_url);
9
10 // 输出url_obj
11 console.log(url_obj);
console:
六、表单提交内容
6.1 表单的重要属性
action: 决定提交到哪里
method: 决定提交的http请求的方式
enctype: 决定提交的数据的发送方式
6.2 控件
表单中能够携带数据的,都可以叫做控件。
比如: input系列 textarea select 等
控件的特点: 有name属性值,那么该控件的内容将会被提交,如果没有,忽略该控件。
6.3 提交表单内容
GET提交数据
1 <form action="/submit" method="get">
2 <div>
3 <p>
4 <label for="username">用户名</label>
5 </p>
6 <p>
7 <!-- 表单中的控件 input系列 select textarea等 它们有共同的属性 name 该属性决定提交的时候的key 如果没有name属性值 此控件中的内容将无法提交 -->
8 <input type="text" name="username" >
9 </p>
10 </div>
11 <div>
12 <p>
13 <label for="password">密码</label>
14 </p>
15 <p>
16 <input type="password" name="password">
17 </p>
18 </div>
19 <div>
20 <!-- button是HTML5新增的一个表单控件 用于表示按钮 该控件有一个特性 如果处在表单内 并且没有type属性 那么默认是一个submit -->
21 <button>提交</button>
22 </div>
23 </form>
填写数据:
点击提交: 因为是get请求,所以会将表单中的数据显示在新页面的地址栏中。
所以,如果使用表单提交数据,那么如果表单中包含隐私信息,请务必使用post提交。
POST提交数据:
1 <form action="/submit" method="post">
2 <div>
3 <p>
4 <label for="username">用户名</label>
5 </p>
6 <p>
7 <!-- 表单中的控件 input系列 select textarea等 它们有共同的属性 name 该属性决定提交的时候的key 如果没有name属性值 此控件中的内容将无法提交 -->
8 <input type="text" name="username" >
9 </p>
10 </div>
11 <div>
12 <p>
13 <label for="password">密码</label>
14 </p>
15 <p>
16 <input type="password" name="password">
17 </p>
18 </div>
19 <div>
20 <!-- button是HTML5新增的一个表单控件 用于表示按钮 该控件有一个特性 如果处在表单内 并且没有type属性 那么默认是一个submit -->
21 <button>提交</button>
22 </div>
23 </form>
填写数据:
提交:地址栏中没有数据了,依然刷新了页面
注: POST请求是有请求正文的。请求正文的容量,理论上没有上限。
查看昵称获取 视频教程、源码笔记、案例