HTTP、模块化

HTTP协议

包括请求行、请求头、请求体

http常见请求方法:

url统一资源请求符,其本身也是一个字符串

响应体的内容格式是非常灵活的,常见的响应体格式有:

1.HTML 2.CSS 3. JavaScript 4.图片 5.视频 6.JSON

响应状态码:

IP本身是一个数字标识IP 用来标志网络设备,实现设备间通信

端口:应用程序的数字标识

作用:实现不同主机应用程序之间的通信

响应报文包含响应行,响应头,响应体

HTTP服务注意事项

https默认端口号是443

创建http服务

javascript 复制代码
// 导入http模块
const http=require('http');
// 创建服务对象
// 请求  响应
const server=http.createServer((request,response)=>{
    response.setHeader('content-type','text/html;charset=utf-8');//设置响应头
    response.end('Hello HTTP Server');//设置响应体
})
// 3.监听端口,启动服务
server.listen(9000,()=>{
    console.log('服务已经启动。。。');
})

获取http请求报文

javascript 复制代码
//1. 导入http模块
const http=require('http');
//2.创建服务对象
// 请求  响应
const server=http.createServer((request,response)=>{
    // 1.声明一个变量
    let body='';
    // 2.绑定事件
    request.on('data',chunk=>{
        body+=chunk;//chunk是buffer,在做加法的时候会转化为字符串
    })
    // 3.绑定end事件
    request.on('end',()=>{
        console.log(body);
        response.end("Hello http");
    })
})
// 3.监听端口,启动服务
server.listen(9000,()=>{
    console.log('服务已经启动。。。');
})

提取HTTP请求报文

查找路径和字符串的两种方式

javascript 复制代码
const http=require('http');
// 1.导入url模块
const url=require('url');
const server=http.createServer((request,response)=>{
    // 2.解析request.url
    let res=url.parse(request.url,true);//第二个属性为true时quire属性将会变成一个对象
    // 路径
    let pathname=res.pathname;
    console.log(pathname);
    // 查询字符串
    let keyword=res.query.keyword;
    console.log(keyword);
    response.end('url');
})
server.listen(9000,()=>{
    console.log('服务已经启动。。。');
})
javascript 复制代码
const http=require('http');
const server=http.createServer((request,response)=>{
    // 实例化url对象
    // let url=new URL('http://www.xxx.com/search?a=100&b=200')
    // let url=new URL('/search?a=100&b=200','http://127.0.0.1');
    let url=new URL(request.url,'http://127.0.0.1');
    // 输出路径
    console.log(url.pathname);
    // 输出keyword查询字符串
    console.log(url.searchParams.get('keyword'));
    response.end('url new');
})
server.listen(9000,()=>{
    console.log('服务已经启动。。。');
})

响应请求练习

javascript 复制代码
const { log } = require('console');
const http=require('http');
const server=http.createServer((request,response)=>{
    // 获取请求的方法
    // let method=request.method;
    let {method}=request;
    // 获取请求的url路径
    let {pathname}=new URL(request.url,'http://127.0.0.1');
    response.setHeader('content-type','text/html;charset=utf-8');
    // 判断
    if(method==='GET' && pathname==='/reg'){
        response.end('注册界面');
    }else if(method==='GET' && pathname==='/login'){
        response.end('登陆界面');
    }else{
        response.end('404 Not Found');
    }
    // response.end('practice');
});
server.listen(9000,()=>{
    console.log('服务器已经启动。');
})

设置HTTP的响应报文

write可以多次调用

每一个请求,在处理的时候必须要执行end 方法的,有且只能有一个end方法

javascript 复制代码
write和end 的两种使用情况:
//1.write和end 的结合使用响应体相对分散
response.write('xx');
response.write('xx');
response.write('xx');
response.end();//每一个请求,在处理的时候必须要执行end 方法的
//2.单独使用end 方法响应体相对集中
response.end('xxx');

练习:列表隔行换色

搭建HTTP服务,响应一个4行3列的表格,并且要求表格有隔行换色效果,且点击单元格能高亮显示

javascript 复制代码
const http=require('http');
//引入fs模块
const fs=require('fs');
const server=http.createServer((request,response)=>{
    // 读取文件内容
    let html=fs.readFileSync(__dirname+'./test.html')
    response.end(html);//end()参数可以是Buffer和字符串
})
server.listen(9000,()=>{
    console.log('服务已经启动');
})

网页资源加载基本过程

网页资源的加载都是循序渐进的,首先获取HTML的的容,然后解析HTML在发送其他资源的请求,如css,Javascript,图片等。理解了这个丙容对于后续的学习与成长有菲常大的帮助

模块练习:网页资源引入

javascript 复制代码
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');
    // 读取文件内容
    // 不能写响应头编码,否则没有效果
    if(pathname==='/'){
        let html=fs.readFileSync(__dirname+'/test.html');
        response.end(html);//end()参数可以是Buffer和字符串
    }else if(pathname==='/index.css'){
        let css=fs.readFileSync(__dirname+'/index.css');
        response.end(css);//end()参数可以是Buffer和字符串
    }else if(pathname==='/index.js'){
        let js=fs.readFileSync(__dirname+'/index.js');
        response.end(js);//end()参数可以是Buffer和字符串
    }else{
        response.statusCode=404;
        response.end('<h1>404 Not Found</h1>')
    }
})
server.listen(9000,()=>{
    console.log('服务已经启动');
})

静态资源服务

静态资源是指内容长时间不发生改变的资源,例如图片,视频,CSS文件,JS文件,HTML文件,字体文件等
动态资源是指内容经常更新的资源,例如百度首页,网易首页,京东搜索列表页面等

静态资源目录与网站根目录

HTTP服务在哪个文件夹中寻找静态资源,那个文件夹就是静态资源目录,也称之为网站根目录

思考:Vscode中使用live-server访问HTML时,它启动的服务网站根目录是谁?

vscode所打开的文件夹

javascript 复制代码
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');
    // 声明一个变量
    let root=__dirname+'/page';
    // let root=__dirname+'/../';//__dirname得到的是当前文件所在的文件夹,../是得到上一级文件夹
    // 拼接文件路径
    let filePath=__dirname+'/page'+pathname;
    // 读取文件 fs 异步api
    fs.readFile(filePath,(err,data)=>{
        if(err){
            response.statusCode=500;
            response.end("文件读取失败~");
            return;//防止代码继续往下执行
        };
        response.end(data);
    })
    // mime插件获取pathname的mime赋值content-type
});
server.listen(9000,()=>{
    console.log('服务已经启动');
});

网页中的URL-绝对路径-相对路径


网页中使用URL的场景小结(包括但不限于)如下场景:

a标签href、link标签href、script标签src、img标签src、video audio标签、srcform中的action、AJAX请求中的URL

设置资源类型(mime类型)

媒体类型(通常称为Multipurpose Internet Mail Extensions或MIME类型)是一种标准,用来表示文档、文件或字节流的性质和格式。

mime类型结构:[type]/[subType]

例如: text/html text/css image/jpeg image/png application/json

HTTP服务可以设置响应头Content-Type来表明响应体的MIME类型,浏览器会根据该类型决定如何处理资源

下面是常见文件对应的mime类型:

对于未知的资源类型,可以选择application/octet-stream类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是我们常见的下载效果

完善静态资源错误处理

请求方法不是GET的时候也会出现错误

javascript 复制代码
const http=require('http');
const fs=require('fs');
const path=require('path');
const server=http.createServer((request,response)=>{
    if(request.method !== 'GET'){
        response.statusCode=405;
        response.end('<h1>404 Not Found</h1>');
        return;
    }
    let {pathname}=new URL(request.url,'http://127.0.0.1');
    let root=__dirname+'/page';
    let filePath=root+pathname;
    fs.readFile(filePath,(err,data)=>{
        if(err){
            response.setHeader('content-type','text/html;charset=utf-8');
            switch(err){
                case 'ENOENT':
                    response.statusCode=404;
                    response.end('<h1>404 Not Found</h1>');
                    break;
                case 'EPERM':
                    response.statusCode=403;
                    response.end('<h1>403 Forbidden</h1>');
                    break;
                default:
                    response.statusCode=500;
                    response.end('<h1>500 Internal Server Error</h1>');
            }
            response.statusCode=500;
            response.end("文件读取失败~");
            return;//防止代码继续往下执行
        };
        // mime插件获取pathname的mime赋值content-type
        // 获取文件后缀名
        let ext=path.extname(filePath).slice(1);//返回的结果是.css,slice(1)从索引1开始
        // 匹配对应的类型
        let type=mimes[ext];
        if(type){
            response.setHeader('content',type+';text/html;charset=utf-8');
        }else{
            // 没有匹配到
            response.setHeader('content-type','application/octet-stream');
        };
        response.end(data);
    })
}).listen(9000,()=>{
    console.log('服务已经启动');
});

GET和POST的区别

GET 和 POST 是 HTTP 协议请求的两种方式。区别:

  1. 作用:
    给服务端新增数据的是post,例如创建新账户;
    向服务端索要资源,加载某些东西是get
  2. 参数位置:
    GET 带参数请求是将参数缀到 URL 之后,在地址栏中输入 url 访问网站就是 GET 请求,
    POST 带参数请求是将参数放到请求体中
  3. POST 请求相对 GET 安全一些,因为在浏览器中参数会暴露在地址栏
  4. GET 请求大小有限制,一般为 2K,而 POST 请求则没有大小限制

模块化

介绍

1.模块化是一个将一个复杂的程序文件依据一定规则(规范)拆分成多个文件的过程

其中拆分出的每个文件就是一个模块,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用

2.模块化项目:编码时是按照模块一个一个编码的,整个项目就是一个模块化的项目

3.模块化的一些好处:减少命名冲突、高复用性、高维护性

模块暴露数据两种方式:

1.module.exports=value

2.exports.name=value

使用时有几点注意:

1.module.exports可以暴露任意数据

2.不能使用exports =value 的形式暴露数据,模块内部module与exports的隐式关系exports =module.exports ={}

require返回的值是module.exports的值不是exports

exports.tiemo=tiemo相当于往{}里添加数据

node.js导入模块

在模块中使用 require 传入文件路径即可引入文件

require 使用的一些注意事项:

  1. 对于自己创建的模块,导入时路径建议写 相对路径 ,且不能省略 ./../
  2. 同名文件查找顺序 .js .json .node
  3. js 和 json 文件导入时可以不用写后缀,c/c++编写的 node 扩展文件也可以不写后缀,但是一
    般用不到
  4. 如果导入其他类型的文件,会以 js 文件进行处理
  5. 如果导入的路径是个文件夹,则会 首先 检测该文件夹下 package.json 文件中 main 属性对应的文件,
    如果 main 属性不存在,或者 package.json 不存在,则会尝试导入文件夹下的 index.jsindex.json ,如果还是没找到,就会报错
  6. 导入 node.js 内置模块时,直接 require 模块的名字即可,无需加 ./../,比如fs、HTTP、path

导入模块的基本流程

require 导入 自定义模块 的基本流程

  1. 将相对路径转为绝对路径,定位目标文件
  2. 缓存检测
  3. 读取目标文件代码
  4. 包裹为一个函数并执行(自执行函数)。通过 arguments.callee.toString() 查看自执行函数
  5. 缓存模块的值
  6. 返回 module.exports 的值

CommonJS模块化规范

module.exportsexports以及require这些都是CommonJS模块化规范中的内容。

而Node.js是实现了CommonJS模块化规范,二者关系有点像JavaScript与ECMAScript

相关推荐
涔溪43 分钟前
HTTP TCP三次握手深入解析
网络·tcp/ip·http
憨子周44 分钟前
2M的带宽怎么怎么设置tcp滑动窗口以及连接池
java·网络·网络协议·tcp/ip
三菱-Liu2 小时前
三菱MR-J4-B伺服连接器和信号排列
网络·驱动开发·硬件工程·制造·mr
WeeJot嵌入式2 小时前
网络安全:挑战、策略与未来趋势
网络
a1denzzz5 小时前
Linux系统的网络设置
linux·服务器·网络
黑客K-ing6 小时前
网络安全名词解释
开发语言·网络·安全·网络安全·php
ZachOn1y7 小时前
计算机网络:运输层 —— 运输层端口号
网络协议·tcp/ip·计算机网络·udp·tcp·端口号
Z pz7 小时前
网络编程——Python简单TCP通信功能代码实践
网络·python·tcp/ip
QQ_7781329747 小时前
信息收集、漏洞扫描、漏洞利用、权限提升、数据泄露
网络·计算机网络
运维小文7 小时前
K8资源之endpoint资源&EP资源
linux·网络·k8s·运维开发