http入门笔记2(HTTP请求和响应)


搞定HTTP请求和响应


要说的话

:本文是用node.js代码实现http,主要是了解用浏览器&curl命令和http服务器之间请求响应的全过程,前段先会简单了解下请求和响应,后段会系统化地学习HTTP,源码+图文解说。 --资料来源饥人谷

前置条件

我希望你看这篇文章时理解什么是URL路径和查询参数,理解IP和端口。如果不知道,可以看我的http入门笔记1(浅析URL),要操作的话需要安装Node.js


i. 先来简单了解下请求和响应

http请求和响应
–图片来源于饥人谷

  • 请求就是客户端里的浏览器发送一个请求到服务器

  • 响应就是服务器拿到这个请求后在同一个端口返回一个响应

1.1 如何发请求呢

  • ①用Chrome地址栏

下图是我输入baidu.com后chrome向www.baidu.com发送的第一个请求

百度请求

  • ②用curl命令

curl是常用的命令行工具,用来请求Web 服务器。它的名字就是客户端(client)的URL 工具的意思

在cmder(或者cmd)里输入curl -v https://www.baidu.com可以清楚的看到请求与响应过程

高亮请求

输入命令后可以看到高亮部分上面是加密过程不用管,高亮部分是发送的请求(’>‘部分),高亮下面是返回的响应(’<'部分)

可以看到代理工具使用的是 curl/7.71.1

代理工具概念:

帮你发请求的工具叫做【用户代理】,英文名是User Agent

1.2 如何做出一个响应呢

要求自己用curl发请求自己响应

Node.js有一个http模块可以做到(我也是粘贴复制饥人谷老师的)

下面是node.js代码服务器完整代码,主要看中间部分,完整的代码在https://github.com/woshidw/node-demo1的server.js里也有

var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]

if(!port){
    
    
  console.log('请指定端口号好不啦?\nnode server.js 8888 这样不会吗?')
  process.exit(1)
}

var server = http.createServer(function(request, response){
    
    
  var parsedUrl = url.parse(request.url, true)
  var pathWithQuery = request.url 
  var queryString = ''
  if(pathWithQuery.indexOf('?') >= 0){
    
     queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
  var path = parsedUrl.pathname
  var query = parsedUrl.query
  var method = request.method

  /******** 从这里开始看,上面不要看 ************/
   console.log('有个傻子发请求过来啦!路径(带查询参数)为:' + pathWithQuery)
/*每次请求都会执行 */
  if(path === '/'){
    
    
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    /*响应的描述信息,text/html我是文本,语法是heml*/
    response.writ  console.log('有个傻子发请求过来啦!路径(带查询参数)为:' + pathWithQuery)
/*每次请求都会执行 */
  if(path === '/'){
    
    
    response.statusCode = 200
    /*成功返回状态码200*/
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    /*响应的描述信息,text/html我是文本,语法是heml*/
    response.write(`
    <!DOCTYPE html>
    <head>
    <link rel="stylesheet" href="/x">
    </head>
    <body>
    <h1>如果路径是/,就发送这段内容,格式为html</h1>
    <h2>我请求了路径为/x的css
    </body>
    `)
    /* 注意:``和''是不同的,``里可以加回车 ,''里回车用\n表示*/
    response.end()
  } else if(path === '/x'){
    
    
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/css;charset=utf-8')
    response.write(`h2{color: green;}`)
    response.end()
  } else {
    
    
    response.statusCode = 404
    /*访问的路径不存在返回状态码为404*/
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(`你访问的页面不存在`)
    response.end()
  }e(`
    <!DOCTYPE html>
    <head>
    <link rel="stylesheet" href="/x">
    </head>
    <body>
    <h1>如果路径是/,就发送这段内容,格式为html</h1>
    <h2>我请求了路径为/x的css
    </body>
    `)
    /*浏览器请求了localhost根目录后,发现根目录要请求一个/x的css,
    于是再次发送请求请求/x,这就是html和css通过http传送到浏览器的整个过程,
    一个路径返回html字符串,一个路径返回css字符串*/
    /* 注意:``和''是不同的,``里可以加回车 ,''里回车用\n表示*/
    response.end()
  } else if(path === '/x'){
    
    
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/css;charset=utf-8')
    response.write(`h2{color: green;}`)
    response.end()
  } else {
    
    
    response.statusCode = 404
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(`你访问的页面不存在`)
    response.end()
  }
  /******** 代码结束,下面不要看 ************/
})

server.listen(port)
console.log('监听 ' + port + ' 成功\n请用在空中转体720度然后用电饭煲打开 http://localhost:' + port)

做出响应主要就围绕上面中间代码进行探讨

  • 这些代码就是服务器代码,一般放在服务器上

  • path是不带查询参数的路径/x

  • query是查询参数的对象形式{a:‘1’}

  • queryString是查询参数的字符串形式?a=1

  • pathWithQuery是带查询参数的路径,一般不用

  • request是请求对象

  • response是响应对象

1.2.1 响应的代码逻辑

①语法

  • ``里面可以回车

  • ’ '里面要回车只能用\n表示

②逻辑

  • 每次收到请求都会把中间的代码执行一遍用if else判断路径,并返回响应
  • 如果是已知路径,一律返回200
  • 如果是未知路径,一律返回404
  • Content-Type表示内容的「类型/语法」
  • response.write()可以填写返回的内容
  • response.end()表示响应可以发给用户了

命令行输入cd +相关绝对路径进入文件,输入以下命令显示的效果
终端

跟随链接进入http://localhost:8888后得到的效果
server效果

开了一个8888的端口,被node.js监听了,如果有人请求了8888这个端口,就会走入node.js代码里,每一次请求就执行一遍上面的代码,改了服务器代码都要重新启动服务器才可以生效

然后再看服务器显示什么

效果1

点击地址访问了路径为/的网页


ii. 系统化学习HTTP

2.1 必须学会什么

  • 基础概念(主要是请求和响应)
  • 如何调试(通过用Node.js,可以用log / debugger)
  • 在哪查资料(用的是Node.js,看Node.js文档)
  • 标准制定者是谁(HTTP规格文档:RFC 2612<RFC 2612专门规定http规则>等)

如何学(CRM学习法)

  • Copy-抄文档、抄老师
  • Run -放在自己的机器上运行成功
  • Modify -加入一点自己的想法,然后重新运行

2.2 HTTP基础概念

1) 请求

  • 请求动词 路径加查询参数 协议名/版本

  • Host:域名或IP

  • Accept: text/ html

  • Content-Type:请求体的格式

  • 回车(请求头和请求体中间加个回车,用于区分)

  • 请求体(也就是上传内容,可以是任意内容,但要在请求体格式里写清楚)

细节

①. 三部分:请求行(红色部分重点)、请求头(蓝色部分)、请求体(绿色部分)

②. 请求动词有GET(获取内容)/POST(上传内容)/PUT/PATCH/DELETE等

③. 请求体在GET请求中一般为空

④. 文档位于RFC 2612第五章

⑤. 大小写不敏感(随意)

下图是请求过程

HTTP请求和响应11

在开发者工具里可以看到请求动词为GET,访问路径为/(没有带查询参数),协议为HTTP,版本号为1.1

Host就是域名和端口号

Accept用来表示接受什么内容,浏览器会默认加上accept就是html或者xhtml+xml或者xml等等(首>先是html,如果没有html也可以接受Xhtml,如过没有Xhtml也可以接受Xml等等)

2) 响应

  • 协议名/版本 状态码 状态字符串

  • Content-Type:响应体的格式

  • 回车

  • 响应体(也就是下载内容)

细节

①三部分:状态行、响应头、响应体

②常见的状态码考点

③文档位于RFC 2612第六章

下图是响应过程

http响应过程

开头就是HTTP/1.1,协议加版本。200是状态码(200代表ok),ok是对200的解释

Content-Type是响应体的格式为(文本,语法为html,字符编码为UTF-8)

在Response可以看响应体,这部分语法格式在Content-Type写好的,如下

response

重点记住请求行状态行,HTTP就很ok了

再记一遍:

  • 请求行是:

请求动词 路径(加查询参数) 协议名/版本

  • 状态行是:

协议名/版本 状态码 状态字符串


iii. 用curl构造请求

主要代码curl -v http://127.0.0.1:8888

简单的请求

原始服务器

  • 设置请求动词

-X POST

curl -v -X POST http://127.0.0.1:8888

可以看到原来的GET变成了POST

POST

注意大小写!!!

  • 设置路径和查询参数

直接在url后面加

curl -v -X POST http://127.0.0.1:8888/xxxx?wd=hi

在地址后面加了路径为/xxxx,查询参数为?wd=h1

锚点是不会传到服务器的

路径和查询参数222

  • 设置请求头

-H 'Name: Value’或者–header ‘Name: Value’

curl -v -X POST -H 'Accept: text/html' http://127.0.0.1:8888/xxxx?wd=hi

把接受任意改成了要接受html的内容

-H

请求头这里可以设置任何奇奇怪怪的内容,服务器都可以读到,比如curl -v -X POST -H 'dw: SB' http://127.0.0.1:8888/xxxx?wd=hi

dw:sb

  • 设置请求体

-d ‘内容’ 或者–data ‘内容’

一般和POST一起

命令行输入
curl -v -X POST -H 'dw: SB' -H 'Content-Type: text/plain;charset=utf-8' -d '请求体内容' http://127.0.0.1:8888/xxxx?wd=hi

我要上传的内容是纯文本,编码是utf-8,要上传的内容就是’请求体内容’五个字

一般1个汉字两个字节
-d


iv. 用node.js读取构造请求

  • 读取请求动词

request.method

console.log('method')

...
 console.log('有个傻子发请求过来啦!路径(带查询参数)为:' + pathWithQuery)
/*每次请求都会执行 */
console.log("method:")//method是
console.log(method);//GET或者POST
...

服务器重启后用curl链接curl http://localhost:8888,服务器得到

读取动词

用curl构造动词curl -X POST http://localhost:8888

读取POST

  • 读取路径

request.url路径,带查询参数

路径写了的后面,该路径可以被读取,就不演示了

path 纯路径,不带查询参数

query只有查询参数

  • 读取请求头

request.headers[‘Accept’]

...
console.log("request.headers:");
console.log(request.headers);//可以通过request.headers拿到所有的请求头
...

用这个 curl -v -H 'dw: SB' http://127.0.0.1:8888

服务器得到所有请求头

所有请求头

  • 读取请求体

v. 用node.js设置响应

  • 设置响应状态码

response.statusCode = 200

可以改动node.js里response.statusCode = xxx来改动状态码

...
 response.statusCode = 200
 /*成功返回状态码200*/
...
  • 设置响应头

response.setHeader(‘Content-Type’, ‘text/html’);

...
response.setHeader('Content-Type', 'text/htmI');
response.setHeader('dw', 'sb');
...

可以通过上面部分修改响应头
响应头

  • 设置响应体

response.write(‘内容’)

可追加内容

response.write(`
    <!DOCTYPE html>
    <head>
    <link rel="stylesheet" href="/x">
    </head>
    `)
    response.write(`
    <body>
    <h1>如果路径是/,就发送这段内容,格式为html</h1>
    <h2>我请求了路径为/x的css
    </body>
    `)

第一次我写head,第二次我写body,可以追加内容,如下,都可以读出来

追加内容





--continue

学习前端从入门到入土,我正在路上。您的每一次观看,就是对我学习路上最大的鼓励,一起努力吧!

欢迎留下您宝贵的意见。

最后,你可能看累了吧,送上一波福利

雷姆

–图片来源于网络

猜你喜欢

转载自blog.csdn.net/weixin_46383761/article/details/112343186
今日推荐