Node-请求响应原理HTTP协议

Posted 我真的爱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node-请求响应原理HTTP协议相关的知识,希望对你有一定的参考价值。


1. 服务器端基础概念

网站的组成:
网站应用程序主要分为两大部分:客户端服务器端

客户端:在浏览器中运行的部分,就是用户看到并与之交互的界面程序。使用html、CSS、javascript构建。

服务器端:在服务器中运行的部分,负责存储数据处理应用逻辑

Node网站服务器:
能够提供网站访问服务的机器就是网站服务器,它能够接收客户端的请求,能够对请求做出响应

IP地址

互联网中设备的唯一标识。
IP是Internet Protocol Address的简写,代表互联网协议地址

查看方式:控制面板–>网络和Internet–>网络和共享中心–>点击连接的网络名称(WLAN状态)—>详细信息
通常IPv4 地址即为我们常说的IP地址(如192.168.0.185)

域名

由于IP地址难于记忆,所以产生了域名的概念,所谓域名就是平时上网所使用的网址
IP => 域名
虽然在地址栏中输入的是网址, 但是最终还是会将域名转换为ip才能访问到指定的网站服务器。

端口

端口是计算机与外界讯息交流的出口,用来区分服务器电脑中提供的不同的服务
(下图左端为客户端服务,右端为服务器端服务)

URL

统一资源定位符,又叫URL(Uniform Resource Locator),是专为标识Internet网上资源位置而设的一种编址方式,平时所说的网页地址指的即是URL。

URL的组成:
传输协议: //服务器IP或域名:端口/资源所在位置标识
网站应用使用协议一般都是http协议
http超文本传输协议(超文本即超级文本,包括图图片、视频、音频等),提供了一种发布和接收HTML页面的方法。

开发过程中客户端和服务端的说明:
在开发阶段,客户端和服务器端使用同一台电脑,即开发人员电脑(开发人员电脑即可以充当服务器也可以充当客户端)。


2. 创建web服务器

网站服务器实际就是一台电脑,在这台电脑中安装node软件。

  //1. 引用系统模块
 const http = require('http');
  //2. 创建web服务器,使用createServer方法
 const app = http.createServer();
  //3. 当客户端发送请求的时候
 app.on('request', (req, res) => {
        //  响应
       res.end('<h1>hi, user</h1>');
 });
  //4. 监听3000端口
 app.listen(3000);
 console.log('服务器已启动,监听3000端口,请访问 localhost:3000')
 //通过localhost:3000就可以访问

3. HTTP协议

HTTP协议的概念:客户端和服务器端沟通的规范
超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答的标准

报文

在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式(以冒号进行分割的键值对)。

报文的查看:
浏览器—>开发者工具---->Network
Response中显示服务器端给客户端响应的具体内容

请求报文:(客户端对服务器端说的话)

  1. 请求方式 (Request Method):一种标识,告诉服务器当前这项请求要做的事情的类型
    • GET 请求数据
    • POST 发送数据
  2. 请求地址 (Request URL)
    req.headers 获取请求报文信息
    req.url 获取请求地址
 app.on('request', (req, res) => {   //req就是请求对象
     req.headers  // !!!获取请求报文信息!!!
     req.headers['accept']    //即获取headers对象下的accept属性信息
     req.url      // !!!获取请求地址!!!(实际就是一个标识,来根据标识响应不同的内容/页面)
     req.method   // 获取请求方法
     
     console.log(req.method)    //对于请求方法的输出
     if (req.method == 'POST') {   //可以根据其响应的方式做一个回应
     	res.end('post')  //显示在页面的响应
     } else if(req.method == 'GET') {
     	res,end('get')
     }
     
 });

method:指定当前表单提交的方式,若不写则默认get方法提交
action:指定当前表单提交的地址

<form method="post" action="http://localhost:3000"></form>

响应报文:(服务器端对客户端说的话)
对于客户端的请求,服务器每次都要给予响应,告诉这次响应是成功的还是失败的

  1. HTTP状态码(通过此方式告诉客户端)
    从开发者工具—Network----Status中查看

    200 请求成功
    404 请求的资源没有被找到
    500 服务器端错误
    400 客户端请求有语法错误(例如请求路线写错了或请求参数不匹配)
    
  2. (返回)内容类型

    text/html
    text/css
    application/javascript
    image/jpeg
    application/json
    
 app.on('request', (req, res) => {
     // 设置响应报文    writeHead:书写响应头
     res.writeHead(200, {
         'Content-Type': 'text/html;charset=utf8'
     });
 });

4. HTTP请求与相应处理

请求参数:
客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作(向服务器传递用户名、密码)。

GET请求参数

  • 参数被放置在浏览器地址栏中,例如:http://localhost:3000/?name=zhangsan&age=20
  • 参数获取需要借助系统模块url,url模块用来处理url地址
 const http = require('http');
 // 导入url系统模块 用于处理url地址
 const url = require('url');
 const app = http.createServer();
 app.on('request', (req, res) => {
     // 将url路径的各个部分解析出来并返回对象
         //参数url.parse表示要解析的url地址  true 代表将参数解析为对象格式
     let {query} = url.parse(req.url, true);     //parse方法表示解析,用来处理url地址,将url地址处理成对象形式,在对象中保存了url各个部分
     console.log(query);
 });
 app.listen(3000);

pathname:获取客户端的请求地址(不包括请求参数的请求地址),将url.parse替换成pathname,用pathname去判断

POST请求参数

  • 参数被放置在请求体(报文)中进行传输
  • post参数没有存放在地址中,是通过事件的方式接收
  • 获取POST参数需要使用data事件(当请求参数传递时触发)和end事件(当参数传递完成时触发)
  • 使用querystring系统模块将参数转换为对象格式
 // 导入系统模块querystring 用于将HTTP参数转换为对象格式   !!!   --->处理请求参数模块
 const querystring = require('querystring');
 app.on('request', (req, res) => {
     let postData = '';
     // 监听参数传输事件
     req.on('data', (chunk) => postData += chunk;);
     // 监听参数传输完毕事件
     req.on('end', () => { 
         console.log(querystring.parse(postData));   //把字符串转成对象,然后输出该方法的返回值
     }); 
 });

路由

http://localhost:3000/index
http://localhost:3000/login
路由是指客户端请求地址服务器端程序代码对应关系。简单的说,就是请求什么响应什么。

实现路由的核心代码
(缺少了对请求方式的判断,对于同一地址,请求方式不同,执行不同的处理逻辑)
实际上,什么样的请求地址对应什么样的请求逻辑均由开发人员所决定

//1. 引入系统模块http
const http = require('http')
//2. 创建网站服务器
const app = http.createServer();
//3. 为网站服务对象添加请求事件
//4. 实现路由功能

 // 当客户端发来请求的时候
 app.on('request', (req, res) => {
     // 获取客户端的请求路径
     let { pathname } = url.parse(req.url);
     if (pathname == '/' || pathname == '/index') {
         res.end('欢迎来到首页');
     } else if (pathname == '/list') {
         res.end('欢迎来到列表页页');
     } else {   //用户输入的请求路径在服务器端没有对应的代码
        res.end('抱歉, 您访问的页面出游了');
     }
 });

静态资源访问

静态资源:
服务器端不需要处理,可以直接响应给客户端的资源就是静态资源,例如CSS、JavaScript、image文件。即浏览器直接运行的文件

静态资源访问:

const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
const app = http.createServer();
app.on('request',(req,res)=> {
	//获取用户的请求路径
	let pathname = url.parse(req.url).pathname;

	pathname == '/' ? '/default.html' : pathname;   //若是/则读取default页面,若不是/,则原本是什么页面就读取什么页面
	
	//将用户的请求路径转换为实际的服务器硬盘路径
	let realPath = path.join(__dirname,'public'+pathname);   //在public文件夹下
	
	//mime模块作用:可以根据当前的请求路径,分析出这个资源的类型,然后把类型通过返回值的方式返回来
	let type = mime.getType(realPath)

	//读取文件
	fs.readFile(realPath,(error,result) => {
		//如果文件读取失败
		if(error != null) {
			res.writeHead(404, {
				'content-type':'text/html;charset = utf8';
			})
			res.end('文件读取失败');
			return;
		}

		res.writeHead(200, {
			'content-type': type;    //mime模块对于任何类型都可以得到响应(不管是css、html、图片)
		})

		res.end(result)
	});
));
app.listen(3000);
console.log('服务器启动成功')

动态资源:
相同的请求地址不同的响应资源(传递不同的响应参数),得到不同的响应结果,这种资源就是动态资源。
例:

http://www.itcast.cn/article?id=1
http://www.itcast.cn/article?id=2

客户端请求途径:
GET方式:

浏览器地址栏
link标签的href属性
script标签的src属性
img标签的src属性
Form表单提交

POST方式:

Form表单提交

以上是关于Node-请求响应原理HTTP协议的主要内容,如果未能解决你的问题,请参考以下文章

请求响应原理以及HTTP协议

请求响应原理及HTTP协议--服务器端基础概念

HTTP工作原理

express开发上手记录(3)知识补充:http请求和响应

http协议与响应请求原理

带你从零学Node.js