HTTP、模块化

HTTP协议

HTTP(hypertext transport protocol)协议;中文叫超文本传输协议、是一种基于TCP/IP的应用层通信协议
这个协议详细规定了 浏览器 和万维网 服务器 之间互相通信的规则。
协议中主要规定了两个方面的内容:

客户端:用来向服务器发送数据,可以被称之为请求报文
服务端:向客户端返回数据,可以被称之为响应报文

请求报文

请求报文包括请求行、请求头、空行、请求体
请求行: 请求方法、url路径、http协议版本

在这里插入图片描述

url统一资源请求符,其本身也是一个字符串
在这里插入图片描述

响应报文:

组成:响应行、响应头、空行、响应体
响应行:
在这里插入图片描述

响应体
响应体的内容格式是非常灵活的,常见的响应体格式有:1.HTML 2.CSS 3. JavaScript 4.图片 5.视频 6.JSON
响应状态码:
在这里插入图片描述
在这里插入图片描述

IP本身是一个数字标识IP 用来标志网络设备,实现设备间通信
在这里插入图片描述
端口:应用程序的数字标识
作用:实现不同主机应用程序之间的通信

HTTP服务注意事项

在这里插入图片描述
https默认端口号是443

创建http服务

// 导入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请求报文

在这里插入图片描述

//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请求报文

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

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('服务已经启动。。。');
})
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('服务已经启动。。。');
})

响应请求练习

在这里插入图片描述

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方法

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列的表格,并且要求表格有隔行换色效果,且点击单元格能高亮显示

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,图片等。理解了这个丙容对于后续的学习与成长有菲常大的帮助

模块练习:网页资源引入

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所打开的文件夹

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的时候也会出现错误

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

  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值