HTTP模块(二)

news2024/11/11 4:43:49

HTTP

设置 HTTP 响应报文

HTTP报文常见属性:

const http = require('http');

const server = http.createServer((request, response) => {
    // 设置请求状态码 2xx 4xx 5xx
    response.statusCode = 200;
    // 设置请求描述 了解即可
    response.statusMessage = 'hello'
    // 指定响应体的MIME类型
    response.setHeader('Content-Type', 'text/html; charset=utf-8');
    // 指定响应内容的编码方式,如gzip或deflate,用于内容压缩。
    response.setHeader('Content-Encoding', 'gzip');
    // 用于实现跨源资源共享(CORS),指定哪些网站可以访问该资源。
    response.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有来源,实际应用中可能需要指定具体来源
    // 指示浏览器如何缓存响应
    response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); // 禁止缓存
    // 一个实体标签,用于验证资源是否有变化
    response.setHeader('ETag', 'W/"abcd1234"');
    // 表示资源最后一次修改的时间。
    response.setHeader('Last-Modified', new Date().toUTCString());
    // 指示服务器软件的信息
    response.setHeader('Server', 'MyCustomServer/1.0');
    // 设置Cookie,用于会话管理等。
    response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
    // 指定响应过期时间,之后浏览器将不再缓存此响应。
    response.setHeader('Expires', new Date(Date.now() + 86400000).toUTCString()); // 一天后过期

    response.end('Hello Http Server');
});

server.listen(9000, () => {
    console.log('服务已启动');
});

加载 HTML 文件内容

HTML 文件如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      td {
        padding: 20px 40px;
      }

      table tr:nth-child(odd) {
        background: pink;
      }

      table tr:nth-child(even) {
        background: red;
      }

      table,
      td {
        border-collapse: collapse;
      }
    </style>
  </head>

  <body>
    <table border="1">
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </table>
    <script>
      //获取所有的 td
      let tds = document.querySelectorAll("td");
      //遍历
      tds.forEach((item) => {
        item.onclick = function () {
          this.style.background = "#ffffff";
        };
      });
    </script>
  </body>
</html>

通过 FS 模块

const http = require('http');
const fs = require('fs');

const server = http.createServer((request, response) => {
    const table = fs.readFileSync(__dirname + `/table.html`);

    response.end(table);
});

server.listen(9000, () => {
    console.log('服务已启动');
});

response.end不仅可以接收字符串作为参数,发送文本数据给客户端,还能够接收 Buffer 对象来发送二进制数据,如图片、音频或视频文件等,需要注意的是使用 Buffer 时,确保你的内容类型(Content-Type)设置与实际数据类型相匹配,以便浏览器或客户端能够正确处理。

网页资源加载基本过程

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>标题</title>
    <link rel="stylesheet" href="./css/index.css" />
  </head>
  <body>
    <h1>这是一个HTML页面</h1>
    <hr />
    <img width="100%" src="./images/h5.png" alt="" />
    <script src="./js/index.js"></script>
  </body>
</html>

在这里插入图片描述

  1. 请求HTML文档:浏览器首先向服务器发送请求以获取HTML文档。这一步通常通过URL完成。
  2. 解析HTML:浏览器开始解析收到的HTML文档,构建DOM(文档对象模型)。解析过程中,浏览器会遇到以下类型的资源:
  • CSS:当遇到link标签引用外部CSS文件或style标签包含内联样式时,浏览器会开始加载CSS(如果是外部链接,则发送CSS请求)。CSS的加载通常与HTML解析并行进行,但CSS的解析(构建CSSOM,即CSS对象模型)可能等待CSS文件完全加载后才进行,以确保正确应用样式。内联样式会立即被处理。
  • IMG 图片:遇到img标签时,浏览器会立即发送请求下载图片,但不会等待图片加载完成就继续解析HTML,以加快页面内容的显示。图片加载通常是异步的。
  • JavaScript:当浏览器遇到script标签时,一般分为同步脚本和异步脚本:
    • 同步脚本:默认情况下,JavaScript的加载和执行会阻塞HTML的解析。浏览器会暂停构建DOM,等待脚本下载并执行完毕。这是因为JavaScript有可能修改DOM结构或CSSOM
    • 异步脚本:如果script标签指定了async属性,脚本会在下载的同时允许HTML解析继续,且脚本下载完成后会异步执行,不保证执行顺序。如果使用defer属性(仅适用于外部脚本),脚本同样不会阻塞HTML解析,但所有带有defer的脚本会在HTML解析完成后,DOMContentLoaded事件触发之前,按照在HTML中出现的顺序执行。
  1. 渲染流程:在解析HTML和加载CSS的过程中,浏览器开始构建渲染树,它是DOMCSSOM的合并产物,表示哪些节点需要如何显示。一旦渲染树构建完成,并且相关资源(如图片)准备就绪,浏览器会开始渲染页面。
  2. 重排与重绘:在页面加载和JavaScript修改DOM/CSSOM时,可能会触发布局重排(Reflow)和样式重绘(Repaint),以反映页面结构或样式的改变。

加载 HTML 文件内容(优化一)

当结构为资源都在响应文件夹下时

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="../css/index.css">
</head>

<body>
  <table border="1">
    <tr>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td></td>
      <td></td>
      <td></td>
    </tr>
  </table>
  <script src="../js/index.js"></script>
</body>
</html>

目录结构

├─css
├─html
├─js
└─服务.js

启动服务.js

const http = require('http');
const fs = require('fs');

const server = http.createServer((request, response) => {
    const table = fs.readFileSync(__dirname + `/html/table.html`);

    response.end(table);
});

server.listen(9000, () => {
    console.log('服务已启动');
});

会发现css样式和js点击功能失效。
在这里插入图片描述
这是由于响应报文均返回html所导致。
在这里插入图片描述
调整代码为以下即可:

//导入 http 模块
const http = require('http');
const fs = require('fs');

//创建服务对象
const server = http.createServer((request, response) => {
  //获取请求url的路径
  let {pathname} = new URL(request.url, 'http://127.0.0.1');
  console.log('pathname', pathname);
  if(pathname === '/'){
    let html = fs.readFileSync(__dirname + '/html/10_table.html');
    response.end(html); 
  }else if(pathname === '/css/index.css'){
    let css = fs.readFileSync(__dirname + '/css/index.css');
    response.end(css); 
  }else if(pathname === '/js/index.js'){
    let js = fs.readFileSync(__dirname + '/js/index.js');
    response.end(js);
  }else{
    response.statusCode = 404;
    response.end('<h1>404 Not Found</h1>')
  }
  
});

//监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

加载HTML文件内容(优化二)

//导入 http 模块
const http = require('http');
const fs = require('fs');
const path = require('path');

//创建服务对象
const server = http.createServer((request, response) => {
  //获取请求url的路径
  let { pathname } = new URL(request.url, 'http://127.0.0.1');
  const filePath = __dirname + pathname;
  fs.readFile(filePath, (err, data) => {
    if (err) {
      response.statusCode = 500;
      return;
    }
    console.log('data', data);
    response.end(data);
  })

加载HTML文件内容(优化三)

const http = require('http');
const fs = require('fs');
const path = require('path');

//声明一个变量
let mimes = {
    html: 'text/html',
    css: 'text/css',
    js: 'text/javascript',
    png: 'image/png',
    jpg: 'image/jpeg',
    gif: 'image/gif',
    mp4: 'video/mp4',
    mp3: 'audio/mpeg',
    json: 'application/json'
}

const server = http.createServer((request, response) => {

    // 拼接路径
    let url = new URL(request.url, 'http://127.0.0.1');

    // 根目录
    let root = __dirname + '/page';

    // 拼接文件路径 css js html ...
    let filePath = root + url.pathname;

    // 读取文件
    fs.readFile(filePath, (err, data) => {
        if (err) {
            console.error(err);
            // 设置字符集
            response.setHeader('content-type', 'text/html;charset=utf-8');
            switch (err.code) {
                case 'ENOENT':
                    response.statusCode = 404;
                    response.end('<h1>404 Not Found</h1>')
                case 'EPERM':
                    response.statusCode = 403;
                    response.end('<h1>403 Forbidden</h1>');
                default:
                    response.statusCode = 500;
                    response.end('<h1>Internal Server Error</h1>');
            };

            return;
        };

        // 获取文件后缀名
        let ext = path.extname(filePath).slice(1);

        // 匹配类型
        let type = mimes[ext];
        if (type) {
            if (ext === 'html') {
                response.setHeader('content-type', type + ';charset=utf-8');
            } else {
                response.setHeader('content-type', type);
            }
        } else {
            //没有匹配到
            response.setHeader('content-type', 'application/octet-stream');
        };

        response.end(data);

    })
});

server.listen('9000', () => {
    console.log('服务已经启动....');
})

GET与POST请求场景

GET

  • 在地址栏直接输入url访问
  • 点击a链接
  • link标签引入css
  • script标签引入js
  • img标签引入脱
  • from标签中的method为get
  • ajax中的get请求

POST

  • form标签中的method为post
  • ajax的post请求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1948286.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nodepad++运行Python文件的方法

windows中使用nodepad运行python文件 首先&#xff0c;需要在windows中安装python解释器。 然后打开nodepad&#xff0c;新建一个文件&#xff0c;输入一段测试的python代码 import socketdef get_hostname():try:# 获取主机名hostname socket.gethostname()return hostna…

uniapp集成安卓原生录屏插件以及使用

概述 我们知道UniApp的出现简化了开发者的工作流程&#xff0c;并减少了代码的重复编写。开发者可以使用一套代码编译到iOS、Android、以及各种小程序的应用&#xff0c;节省了人力和时间成本&#xff0c;但是涉及到与系统交互的时候&#xff0c;比如录屏、录音、录像、文件操…

Go语言常见序列化协议全面对比

先说结论 从易用性、性能、内存占用、编码后大小等几个方面综合考虑 ProtoBuf 胜出。 Gob 从性能和 I/O 带宽占用上都和 ProtoBuf 差不多&#xff0c;唯一劣势是编解码时内存占用较多。考虑到不用再写 IDL 带来的易用性&#xff0c;如果整个系统内不存在使用除 Go 以外其他语言…

『Django』搭建你的博客网站

theme: smartblue 点赞 关注 收藏 学会了 本文简介 如果你学了我前面写的 Django 文章&#xff0c;现在已经有能力去试试自己搭建博客网站了。 虽然用的不是现在流行的前后端分离的方式(前后端分离的方式会在之后的文章讲解)。 但在搭建网站之前我们还要做一些额外的功能让你…

【机器学习】梯度下降的基本概念和如何使用梯度下降自动化优化w和b

引言 梯度下降是一种用于寻找函数最小值的优化算法&#xff0c;它在机器学习中广泛用于训练模型&#xff0c;如线性回归、神经网络等 一、梯度下降的基本概念 1.1 目标函数 在机器学习中&#xff0c;这通常是损失函数&#xff08;如均方误差、交叉熵等&#xff09;&#xff0…

[渗透测试] 主动信息收集

主动信息收集 在红蓝对抗过程中&#xff0c;资产属于核心地位&#xff0c;攻击方&#xff08;红方&#xff09;要尽可能的去获取对方资产&#xff0c;暴露目标资产&#xff0c;包括IP地址、网络设备、安全设备、服务器、存储在服务器中的数据等。防守方也要清楚自己有多少有价…

了解网络是如何运作

“Web 的工作原理”提供了一个简化的视图,用于了解在计算机或手机上的 Web 浏览器中查看网页时发生的情况。 这个理论对于短期内编写 Web 代码来说并不是必需的,但不久之后,你就会真正开始从理解后台发生的事情中受益。 客户端和服务器 连接到 Internet 的计算机称为客户端和…

dns逆向解析,主从服务,多域名访问(穿插ntp服务器)

复习 域名解析&#xff1a; 正向解析&#xff1a;将域名解析为ip 反向解析&#xff1a;将ip解析为域名 逆向解析 关闭防火墙和selinux&#xff0c;配置静态ip [rootdns ~]# vim /etc/named.rfc1912.zones [rootdns ~]# vim /etc/named.conf [rootdns ~]# cd /var/named/ [rootd…

刚购买的阿里云服务器该如何配置环境(CentOS)

文章目录 购买开始初始设置登录云服务器安装 Apache 服务安装 MySQL安装 PHP快照 第三方 SSH 登录笔者的话 购买 按照需求购买就行。学生有免费试用一个月的活动&#xff0c;可以试着玩玩。 开始初始设置 登录云服务器 购买完后&#xff0c;点击实例&#xff0c;点击实例名…

Linux下RDMA驱动程序探索系列-2

本系列文章将带领读者逐步了解Linux操作系统下的RDMA子系统。本篇文章作为系列的第二篇&#xff0c;将深入内核态驱动程序的代码&#xff0c;主要介绍如下内容&#xff1a; Driver的初始化流程几个重要verbs回调函数的简介 01、Kernel Driver的初始化流程 由于不同厂商的驱动…

进销存系统开发,含税小计和含税单价计算,含税和不含税,1000元电脑为案例

if (data ! null) {console.log("中断调试&#xff0c;2024-7-25 最终计算税务");//删除不需要会报错var 未来之窗_人工智能_计算_税额 parseFloat((data.price * data.num * data.tax_rate / 100 ).toFixed(2));var 未来之窗_人工智能_计算_含税小计 parseFloat((…

js轮播图制作

实现一个简单的JavaScript轮播图可以通过以下步骤完成&#xff1a; 创建HTML结构&#xff0c;包括轮播图容器和图片列表。 使用CSS进行样式设置&#xff0c;包括隐藏多余的图片。 使用JavaScript编写函数来控制图片的切换。

07-15 周一 lmdeploy导出迁移因子到量化模型中

07-15 周一 lmdeploy导出迁移因子到量化模型中 时间版本修改人描述2024年7月15日14:57:02V0.1宋全恒新建文档 简介 方案设计 由于norm层的前后导致smoothquant执行量化不好融合&#xff0c;为了降低我事先的难度&#xff0c;所以就不再融合normalization的算子了&#xff0c…

vue3编程-import.meta.glob实现动态路由(菜单)

import.meta.glob 是vite提供的批量懒加载组件的方法 本地开发环境&#xff1a; const modules import.meta.glob(../views/**/*.vue)这段代码返回的modules是一个Map&#xff1a; key是vue文件的相对路径&#xff0c;值是一个函数&#xff0c;将函数打印出来&#xff0c;如…

【微信小程序实战教程】之微信小程序原生开发详解

微信小程序原生开发详解 微信小程序的更新迭代非常频繁&#xff0c;几乎每个月都会有新版本发布&#xff0c;这就会让初学者感觉到学习的压力和难度。其实&#xff0c;我们小程序的每次版本迭代都是在现有小程序架构基础之上进行更新的&#xff0c;如果想要学好小程序开发技术&…

配置mysql8.0.21版本docker-compose启动容器

1. 总览 2 docker-compose.xml配置 version: 3 services:mysql:image: 192.168.188.131:8000/mysqlrestart: alwaysvolumes:- ./data:/var/lib/mysql- ./my.cnf:/etc/mysql/my.cnf- ./mysql-files:/var/lib/mysql-files- ./log/mysql:/var/log/mysqlenvironment:MYSQL_ROOT_PA…

Shell实现服务自动部署

一、环境 注意&#xff1a; nfs.example.com应该为nfs.exam.com 172.25.250.101-172.25.250.105 共 5 个 IP 地址由servera.exam.com服务器进行提供。 172.25.250.106 由 serverb.exam.com 服务器进行提供。 二、需求 项目需求&#xff1a; 1. 172.25.250.101 主机上的 W…

UEFI DebugLib 介绍

1.我们调试中常用Debug 打印信息&#xff0c;这些会输出到BIOS串口日志中 EFI_STATUSEFIAPIHelloWorld2(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable){EFI_STATUS Status;StatusEFI_SUCCESS;gST->ConOut->OutputString(gST->ConOut,L&q…

如何保护您的 WordPress 不被黑?

明月可以说是见到过太多 WordPress 网站被黑的示例了&#xff0c;加上平时明月也会接一些 WordPress 疑难杂症的解决服务订单&#xff0c;所以这方面绝对是专业对口了。作为一个资深 WordPress 博客站长&#xff0c;谁都有被黑过的经历&#xff0c;都是一步步走过来的&#xff…

从零入门AI for Science(AI+化学)#Datawhale AI 夏令营

基于天池平台“第二届世界科学智能大赛 物质科学赛道&#xff1a;催化反应产率预测”使用平台 我的Notebook 魔搭社区 https://modelscope.cn/my/mynotebook/preset 赛事官网 上海科学智能研究院 http://competition.sais.com.cn/competitionDetail/532233/myScore Task1 …