请求响应原理及HTTP协议:服务器端基础概念、创建web服务器、HTTP协议、HTTP请求与响应处理、Node.js异步编程

本文详细介绍了网站的组成,包括客户端和服务器端,重点讲解了Node.js创建Web服务器的过程,以及HTTP协议的基本概念如请求和响应报文。同时,探讨了HTTP请求参数的处理,包括GET和POST方式,以及路由、静态资源和动态资源的区分。此外,还讨论了Node.js中的异步编程,包括同步API和异步API的区别,以及如何通过回调函数、Promise和异步函数来处理异步操作。
摘要由CSDN通过智能技术生成

1、服务器端基础概念

1.1 网站的组成

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

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

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

在这里插入图片描述

1.2 Node网站服务器

能够提供网站访问服务的机器就是网站服务器,它能够接收客户端的请求,能够对请求做出响应
在这里插入图片描述

1.3 IP地址、域名、端口

(1) IP地址

互联网中设备的唯一标识。

IPInternet Protocol Address 的简写,代表互联网协议地址。
在这里插入图片描述
(2)域名

由于 IP 地址难于记忆,所以产生了域名的概念,所谓域名就是平时上网所使用的网址。

http://www.itheima.com => http://124.165.219.100/

虽然在地址栏中输入的是网址,但是最终还是会将域名转换为 ip 才能访问到指定的网站服务器。

(3)端口

端口是计算机与外界通讯交流的出口,用来区分服务器电脑中提供的不同的服务。
在这里插入图片描述

1.4 URL

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

URL 的组成:

传输协议://服务器IP或域名:端口/资源所在位置标识

http://www.itcast.cn/news/20181018/09152238514.html

http超文本传输协议,提供了一种发布和接收 HTML 页面的方法。

1.5 开发过程中客户端和服务器端说明

在开发阶段,客户端和服务器端使用同一台电脑,即开发人员电脑。

在这里插入图片描述

2、创建web服务器

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

3、HTTP协议

3.1 HTTP协议的概念

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

在这里插入图片描述

3.2 报文

在 HTTP 请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式。

在这里插入图片描述

3.3 请求报文

(1)请求方式 (Request Method)

  • GET 请求数据
  • POST 发送数据

(2)请求地址 (Request URL)

 app.on('request', (req, res) => {
     req.headers  // 获取请求报文
     req.url      // 获取请求地址
     req.method   // 获取请求方法
 });

3.4 响应报文

(1)HTTP状态码

  • 200 请求成功
  • 404 请求的资源没有被找到
  • 500 服务器端错误
  • 400 客户端请求有语法错误

(2)内容类型

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

4、HTTP请求与响应处理

4.1 请求参数

客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作。
在这里插入图片描述

4.2 GET请求参数

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

4.3 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)); 
     }); 
 });

4.4 路由

http://localhost:3000/index
http://localhost:3000/login

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

在这里插入图片描述

 // 当客户端发来请求的时候
 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('抱歉, 您访问的页面出游了');
     }
 });

4.5 静态资源和动态资源

(1)静态资源

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

http://www.itcast.cn/images/logo.png
在这里插入图片描述
(2)动态资源

相同的请求地址不同的响应资源,这种资源就是动态资源。

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

在这里插入图片描述

4.6 客户端请求途径

(1) GET方式

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

(2)POST方式

  • Form 表单提交

在这里插入图片描述

5、Node.js异步编程

5.1 同步API,异步API

 // 路径拼接
 const public = path.join(__dirname, 'public');
 // 请求地址解析
 const urlObj = url.parse(req.url);
 // 读取文件
 fs.readFile('./demo.txt', 'utf8', (err, result) => {
     console.log(result);
 });

(1)同步API:只有当前API执行完成后,才能继续执行下一个API

console.log('before'); 
console.log('after');

(2)异步API:当前 API 的执行不会阻塞后续代码的执行

console.log('before');
setTimeout(
   () => { console.log('last');
}, 2000);
console.log('after');

5.2 同步API,异步API的区别( 获取返回值 )

同步 API 可以从返回值中拿到 API 执行的结果,但是异步 API 是不可以的。

在执行同步 API 或函数时,代码执行的结果是通过返回值获取到的,但异步 API 的的结果是无法通过返回值得到的,需要通过回调函数获取。

    // 同步
  function sum (n1, n2) { 
      return n1 + n2;
  } 
  const result = sum (10, 20);
  // 异步
  function getMsg () { 
      setTimeout(function () { 
          return { msg: 'Hello Node.js' }
      }, 2000);
  }
  const msg = getMsg ();

5.3 回调函数

回调函数:自己定义函数让别人去调用。

 // getData函数定义
 function getData (callback) {}
 // getData函数调用
 getData (() => {});

5.4 使用回调函数获取异步API执行结果

function getMsg (callback) {
    setTimeout(function () {
        callback ({ msg: 'Hello Node.js' })
    }, 2000);
}
getMsg (function (msg) { 
    console.log(msg);
});

5.5 同步API,异步API的区别(代码执行顺序)

(1)同步 API 从上到下依次执行,前面代码会阻塞后面代码的执行。

for (var i = 0; i < 100000; i++) { 
    console.log(i);
}
console.log('for循环后面的代码');

(2)异步 API 不会等待 API 执行完成后再向下执行代码。

console.log('代码开始执行'); 
setTimeout(() => { console.log('2秒后执行的代码')}, 2000);
setTimeout(() => { console.log('"0秒"后执行的代码')}, 0); 
console.log('代码结束执行');

代码执行顺序分析:
在这里插入图片描述
在这里插入图片描述

5.6 Node.js中的异步API

 fs.readFile('./demo.txt', (err, result) => {});
 var server = http.createServer();
 server.on('request', (req, res) => {});

如果异步 API 后面代码的执行依赖当前异步 API 的执行结果,但实际上后续代码在执行的时候异步 API 还没有返回结果,这个问题要怎么解决呢?

fs.readFile('./demo.txt', (err, result) => {});
console.log('文件读取结果');

5.7 Promise

Promise 出现的目的是解决 Node.js 异步编程中回调地狱的问题。

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        if (true) {
            resolve({name: '张三'})
        }else {
            reject('失败了') 
        } 
    }, 2000);
});
promise.then(result => console.log(result); // {name: '张三'})
       .catch(error => console.log(error); // 失败了)

5.8 异步函数

异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了。

const fn = async () => {};
async function fn () {}

(1)async 关键字

  1. 普通函数定义前加 async 关键字,普通函数变成异步函数。
  2. 异步函数默认返回 promise 对象。
  3. 在异步函数内部使用 return 关键字进行结果返回,结果会被包裹的 promise 对象中,return 关键字代替了 resolve 方法。
  4. 在异步函数内部使用 throw 关键字抛出程序异常。
  5. 调用异步函数,再链式调用 then 方法获取异步函数执行结果。
  6. 调用异步函数,再链式调用 catch 方法获取异步函数执行的错误信息。

(2)await 关键字

  1. await 关键字只能出现在异步函数中。
  2. await promise await 后面只能写 promise 对象,写其他类型的 API 是不可以的。
  3. await 关键字可以暂停异步函数向下执行,直到 promise 返回结果。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值