4、Node.js---HTTP协议

(一)什么是HTTP协议?

超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议

 (二)请求报文结构

请求体有非空和空的

请求行 

1、 请求方法: 

2、URL:

(Uniform Resource Locator,统一资源定位器

URL组成:协议名+主机名(定位网络上的计算机)+路径(定位服务器中的资源)

3、 HTTP版本号:

请求头

 1、键值对格式

2、主要记录了浏览器相关信息

3、User-Agent:记录浏览器的平台、版本号

4、Accept:浏览器能够处理的数据类型

5、Accept-Encoding:当前浏览器能支持浏览器的方式

6、Accept-Language:当前浏览器所支持的语言

7、Upgrade-Insecure-Request:升级HTTP为HTTPS提高安全性

HTTP 标头(header) - HTTP | MDN       (详细学习HTTP)

请求体

请求体的格式没有定义,用的比较多的是键值对(JSON格式)

(三)响应报文结构与响应行 

响应行结构:

 响应状态码: 

响应状态描述:基本和响应状态码对应 

HTTP 响应状态码 - HTTP | MDN   (陌生响应状态码可在此处查询)

响应头:

1、Server:记录服务器所使用的技术

2、Date:记录响应时间

3、Content-Type:声明响应体格式与字符集。(重要)

响应体: 

常见的响应体格式:

 扩展:

HTTP抓取工具:

Fiddler抓包工具简介,安装及使用教程详解_Sunny蔬菜小柠的博客-CSDN博客

==================================分隔线=================================

(一)创建HTTP服务端

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

//创建服务对象
const server = http.createServer((request,response)=>{
    response.end('Hello HTTP Server');//设置响应体
});

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

可以看到9000端口已经被node.js的脚本程序占用了,那么谁能给他发送请求呢?浏览器能!

(二)HTTP服务的注意事项:

找到被占用的端口,记住他的PID ,打开任务管理器

找到对应的PID,右击停止。

 (三)用过浏览器查看HTTP报文

网页右击检查

 写一个页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:9000/" method="post" >
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

按提交就会跳转:http://127.0.0.1:9000/

 

源代码是这一串字符串 

(四)获取HTTP请求报文

 (五)提取URL中的路径(第一种方法)

//导入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)
    //路径
    let pathname=res.pathname;
    //查询字符串
    let keyword = res.query.keyword;
   console.log(keyword)
    response.end('url')
});

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

提取URL中的路径(第二种方法)

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


//创建服务对象
const server = http.createServer((request,response)=>{
  //实例化URL对象
    let url= new URL(request.url,'http://127.0.0.1');
    //输出路径
    console.log(url.pathname);
    //输出字符串
    console.log(url.searchParams.get('keyword'));
    response.end('url')
});

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

HTTP请求联系

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

//创建服务对象
const server = http.createServer((request,response)=>{
  //获取请求方法
    let {method}= request;//解构赋值的方式,因为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==='/login'){
        //登录情形
        response.end('登录页面');
    }else if (method ==='GET'&& pathname==='/reg') {
        response.end('注册页面');
    }else {
        response.end('Not Found')
    }
});

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


 (五)设置HTTP响应报文

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

//创建服务对象
const server = http.createServer((request,response)=>{
    //设置响应那个状态码
    response.statusCode=203;

    //设置响应状态的描述
    response.statusMessage='nihao'; //在一般状态下,响应状态描述一般跟响应码一一对应,所以这一块了解即可

    //响应头
    response.setHeader('content-type','text/html;charset=utf-8')
    //响应头还可以设置别的
    response.setHeader('Server','Node.js')//Server是用来标识服务端的名字
    //自定义响应头
    response.setHeader('myHeader','woshichengxuyuan')
    //设置多个同名响应头
    response.setHeader('test',['a','b','c']);

    //响应体设置
    response.write('nihao');//write方法可以多次调用,end方法只能有一个
    response.write('hello');
    response.end('Not Found')//设置响应体

});

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


 HTTP响应练习

js代码:

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

//创建服务对象
const server = http.createServer((request,response)=>{
    //读取文件内容
    let html= fs.readFileSync(__dirname+'/01.html')
    response.end(html)//设置响应体

});

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


html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        td{
            padding: 20px 40px;
        }
        table tr:nth-child(odd){
            background: #aef;
        }
        table tr:nth-child(even){
            background: #fcb;
        }
        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>
    <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='#222'
        }
    })
</script>
</body>
</html>

 

练习:实现网页引入外部资源

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
   <link rel="stylesheet" href="01.css">
</head>
<body>
<table border="1">
    <tr><td></td><td></td><td></td></tr>
    <tr><td></td><td></td><td></td></tr>
    <tr><td></td><td></td><td></td></tr>
    <tr><td></td><td></td><td></td></tr>

</table>
<script src="01.js"></script>
</body>
</html>

css代码:

td{
    padding: 20px 40px;
}
table tr:nth-child(odd){
    background: #aef;
}
table tr:nth-child(even){
    background: #fcb;
}
table,td{
    border-collapse: collapse;
}

js代码:

//获取所有的td
let tds = document.querySelectorAll('td');
//遍历
tds.forEach(item =>{
    item.onclick = function(){
        this.style.background='#222'
    }
})

功能代码:

//导入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');
    if (pathname==='/'){
        //读取文件内容
        let html= fs.readFileSync(__dirname+'/01.html')
        response.end(html)//设置响应体
    }else  if(pathname==='/01.css'){
        //读取文件内容
        let css= fs.readFileSync(__dirname+'/01.css')
        response.end(css)//设置响应体
    }else if (pathname==='/01.js'){
        //读取文件内容
        let js= fs.readFileSync(__dirname+'/01.js')
        response.end(js)//设置响应体
    }else {
        response.statusCode=404
        response.end('<h1>404 Not Found</h1>')
    }


});

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


结果:

html响应html页面

 css响应css页面

js响应js页面

但是这种方法很麻烦,要写很多if-else,还有更好的方法吗?

 (六)用HTTP模块搭建静态资源服务

主要代码:

//导入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');
    //拼接文件路径
    let filePath=__dirname+'/page'+pathname;
    // console.log(filePath)
    //读取文件fs 异步API
    fs.readFile(filePath,(err,data)=>{
        if (err){
            response.statusCode=500;
            response.end('读取失败');
            return;
        }
        //响应文件内容
        response.end(data)
    })

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


结果: 

(七) 网站根目录或静态资源目录

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

(八)网页URL之绝对路径

网页中的 URL 主要分为两大类:相对路径与绝对路径
绝对路径:
绝对路径可靠性强,而且相对容易理解,在项目中运用较多

 第一种和第三种用的比较多。

(八)网页URL之相对路径

相对路径在发送请求时,需要与当前页面 URL 路径进行 计算 ,得到完整 URL 后,再发送请求,学习阶段用的较多
例如当前网页 url http://www.atguigu.com/course/h5.html (当前文件夹是course)

 ./是当前文件夹,../是上一级目录

(九)MIME类型(媒体类型)资源类型 

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

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

例如: text/html text/css image/jpeg image/png application/json
HTTP 服务可以设置响应头 Content-Type 来表明响应体的 MIME 类型,浏览器会根据该类型决定如何处理资源
常见文件对应的 mime 类型

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'

规范一点写法,但是没必要。

//导入Http模块
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)=>{
    //获取请求url的路径
    let {pathname} = new URL(request.url,'http://127.0.0.1');
    //拼接文件路径
    let filePath=__dirname+'/page'+pathname;

    //读取文件fs 异步API
    fs.readFile(filePath,(err,data)=>{
        if (err){
            response.statusCode=500;
            response.end('读取失败');
            return;
        }
        //获取文件后缀名
        let ext= path.extname(filePath).slice(1)
        //获取对应的类型
        let type = mimes[ext];
        if (type){
            //匹配到了
            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 标签引入图片
  • form 标签中的 method get (不区分大小写)
  • ajax 中的 get 请求  
POST 请求的情况:
  • form 标签中的 method post(不区分大小写)
  • AJAX post 请求

GETPOST请求的区别  

GET POST HTTP 协议请求的两种方式。
  • 作用不同:GET 主要用来获取数据,POST 主要用来提交数据
  • 参数位置不同:GET 带参数请求是将参数缀到 URL 之后,在地址栏中输入 url 访问网站就是 GET 请求,POST 带参数请求是将参数放到请求体中
  • 安全性不同:POST 请求相对 GET 安全一些,因为在浏览器中参数会暴露在地址栏
  • GET 请求大小有限制,一般为 2K,而 POST 请求则没有大小限制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值