js http请求_前端也得懂点儿 HTTP (下)

9ced750cc6f2cf3835c592aa0f1d316d.png

先导

  • 安装 Node.js 8+
  • 理解 IP 和 端口
  • 理解 URL 路径和查询参数

演示 Node.js Server ⭐

请求与响应模型

ca1b85c763a052fdad50ed08ad549565.png
  • 服务器,就是没有显示器的电脑

如何发请求

方法

  • 用 Chrome 地址栏
  • 用 curl 命令

概念

  • 帮你发请求的工具叫做「用户代理」
    • 如果使用 Chrome 地址栏发送请求,那么 Chrome 就是我们的「用户代理」
    • 如果使用 curl 命令发送请求,那么 curl 就是我们的「用户代理」
  • 「用户代理」 英文名 User Agent

如何做出一个响应 ⭐

用 Chrome 地址栏 或 用 curl 命令 ,可以发出一个请求
  • 那么如何做出一个响应呢?(演示自己发请求-自己响应的过程)

需要用到编程

  • Node.js 有一个 http 模块可以做到
  • 新建项目目录 node-demo / server.js,将下面代码粘入 ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 代码细节先不管,直接复制使用。(注意这块目的不是学 nodejs,而是搞清楚 http 的请求和响应)
 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')
  response.write(`二哈`)
  response.end()
   } else if (path === '/x') {
  response.statusCode = 200
  response.setHeader('Content-Type', 'text/css;charset=utf-8')
  response.write(`body{color: red;}`)
  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 是响应对象
  • n 表示回车

运行机制⭐

在终端中启动应用:

    1. 运行 node server.js 未指定端口号,会有提示
    2. 按照提示执行即可 node server.js 8888 或者 node server 8888 这句话就意味着我们的电脑会开一个端口 8888,这个端口被 server.js 监听着
    3. 这时候只要有人请求了8888 端口,就会走入 server.js 的代码中,我们注释的那段代码就会运行一遍。每接收到一次请求,就运行一遍
用 curl 发出请求 curl http://127.0.0.1:8080/xxxx。server.js 接收到请求,会做出响应。

e3b75f507e51c11dd99c008536dd169a.png

8bfd4356e7faed63d7befe29b1867846.png
    • 如果响应内容乱码,可能是 windows 系统的关系

添加路由

    1. 编辑 server.js 文件,添加 if else(限定条件,访问某个路径,响应对应内容)
    2. 重新运行 node server.js 8888(修改服务代码,需要重启)
if (path === '/') {
  console.log('有人访问/了')
  response.end('这就是访问/,响应的内容n')   // 回车n
} 

b9a2df709ac4306f8e7739b6bc24381e.png


下面是,server.js 监听到 curl 命令 请求根路径时 执行的 console.log(…)

60fed5811861f8f6026a10e25fc0ec08.png

后台启动应用:

    1. touch log 创建一个 log 文件
    2. node server.js 8888 >log log 2>&1 &
      返回的数字1144就是这个进程的 ID(目前这个进程已经在后台运行了)

5e31d4f0d795029c75dcbcdc2132f369.png
    • 运行后,服务器在后台启动,不占用当前终端
    • 怎么关闭这个后台进程呢?
      • 执行 kill -9 xxxx xxxx为后台进程的 id数字
      • kill -9 是最厉害的杀进程的方法

代码逻辑

语法

 `这种字符串` 里面可以回车
 '这种字符串' 里面要回车,只能用 n 表示

逻辑

  1. 每次收到请求都会把中间的代码执行一遍
  2. 用 if else 判断路径,并返回响应
  3. 如果是已知路径,一律返回 200
  4. 如果是未知路径,一律返回 404
  5. Content-Type 表示内容的「类型/语法」(省略后缀,程序员从来不看后缀 ,后缀只是用来告诉计算机要用什么软件打开文件)
    `text/html`、`text/css`
    path 不写 /x.css 而写 /x,因为 content-type 中已经声明了类型/语法,所以可省略后缀 .css
  6. response.write() 可以填写返回的内容(写入响应内容)
  7. 调用 response.end() 表示响应可以发给用户了(调用 response.end() ,就会将响应发送给浏览器)
    ( 以前不写 end 就会一直等待,现在可能优化了可以不写 end,严谨起见还是都写完整,明确告知可以响应给用户了 )
  if (path === '/') {
  response.statusCode = 200
  response.write(`
   <!DOCTYPE html>
   <head>
     <meta charset="UTF-8">
    <link rel="stylesheet" href="/x">  // <<<<<<<<<<<<<<<<<< 将 html 和 css 结合起来
   </head>
   <body>
     <h1>标题</h1>
    </body>
  `)
  response.end()
   } else if (path === '/x') {
  response.statusCode = 200
  response.setHeader('Content-Type', 'text/css;charset=utf-8')
  response.write(`body{color: red;}`)
  response.end()
   }
 

1981a875b58e28e143131499e1a454c6.png
    • 如上图就是,通过 link 把 html 和 css 联系起来,成为一个网页,把这个网页通过 http 传送到浏览器上的整个过程:一个路径返回 html 字符串,一个路径响应 css 字符串。
    • 这就是李爵士发明的 URL + HTTP + HTML

注意符号 ``

反引号 `` 可以识别回车、语法
单引号 ‘’ 不能识别回车语法,仅作为字符串

8f4445042823a32461b48a3f04cf4c1b.png

遥想当年李爵士

世界上第一个服务器程序

  • 我们也写一个服务器程序

世界上第一个网页

  • 我们在 / 路径返回一个 HTML 内容
  • 然后在 /x 路径返回一个 CSS 内容
  • 然后再 /y 路径返回一个 JS 内容
  if (path === '/') {
  response.statusCode = 200
  response.write(`
   <!DOCTYPE html>
   <head>
     <meta charset="UTF-8">
    <link rel="stylesheet" href="/x">   ←←←←←←←←←←←←←← 引入 css
   </head>
   <body>
     <h1>标题</h1>
     <script src="/y"><script>   ←←←←←←←←←←←←←←← 引入 js
    </body>
  `)
  response.end()
   } else if (path === '/x') {
  response.statusCode = 200
  response.setHeader('Content-Type', 'text/css;charset=utf-8')
  response.write(`body{color: red;}`)
  response.end()
   } else if(path === "/y"){
  response.statusCode = 200;
  response.setHeader("Content-Type", "text/javascript;charset=utf-8");
  response.write(`console.log('这是JS内容')`;
  response.end();
   } else {
  response.statusCode = 404;
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
  response.write(`你输入的路径不存在对应的内容`)
  response.end()
   }

注意事项

  • 关于后缀
    • 即使写成 path === "/y.css" ,但如果在 Content-Type 中规定是 js 类型,就会按照 js 解析。所以,URL里的css 后缀卵用没有
    • Content-Type 才是决定文件类型的关键

体系化学习 HTTP

必须学会什么

  • 基础概念(有哪些是必会的)
    • 请求、响应
  • 如何调试(用的是 Node.js,可以用 log / debugger )
    • 本质是学习 HTTP,所以不要在 Nodejs 花费太多时间,只需要搞懂 nodejs 怎么调试即可
  • 在哪查资料(用的是 Node.js,所以看 Node.js 文档)
  • 标准制定者是谁( HTTP 规格文档:RFC2616(中文)等)

如何学

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

HTTP 基础概念

  • 必须点击 view source ,才能看到完整的请求、响应

d771dceb75bc8acda69f1cc13695daf2.png

请求

e6862f4273ffe51ea90c884d83efb01e.png
  • 请求动词 路径加查询参数 协议名/版本(所有请求都按照这个格式,简化版)例:GET /x?wd=hi HTTP/1.1
  • Host: 就是域名或 IP(包括端口号)
  • Accept: text/html(表示浏览器想接收什么内容)
    • 测:根据 accept 返回不同内容
 var accept = request.headers['accept'];  // 获取请求头中的 accept 的值,赋给变量
 if(accept.indexOf('xml')){
  response.write('我知道你想访问 XML 内容')
 }else{
  response.write(`<!DOCTYPE html><html>...</html>`)
 }
    • 浏览器可接收的内容:accept。(大多来说浏览器就是接收 html)
      默认先找 html,如果没有 html,可以接收 xhtml、xml、webp、png、igned-exchange(如下)
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.
  • Content-Type: 表示请求体的格式(例:text/javascript;charset=utf-8)
  • 回车(划分请求头、请求体的界线)
  • 请求体(也就是上传内容)

细节

  • 请求有三部分,用回车隔开,分别是:(与 ↑↑ 对应颜色)
    • 请求行(因为只有一行,所以叫请求行)GET /x?wd=hi HTTP/1.1
    • 请求头
    • 请求体(请求体的格式,是在 content-type 中指定的)
  • 请求动词有 GET / POST / PUT / PATCH / DELETE 等
    • GET 用于获取内容
    • POST 用于上传内容
      发送post请求:curl -v -X POST --data '上传内容' http://localhost:8888/

cf4bcbb56a09312aedfaf18f5df1048b.png
  • 请求体在 GET 请求中一般为空
    • 因为get请求通常用于获取内容,而请求体表示要上传的内容,所以GET请求一般没有请求体
  • 文档位于 RFC2616 第五章
  • 大小写不敏感(随意),最好照着我的写

响应

304c7088a9d15af3fb372381e93e4f31.png
  • 协议名/版本 状态码 状态字符串
  • Content-Type: 响应体的格式
  • 回车
  • 响应体(也就是下载内容)

细节

  • 响应有三部分,用回车隔开,分别是:
    • 状态行(Status LIne)
    • 响应头
    • 响应体(响应体的格式,在Content-Type中指定)
  • 常见的状态码是考点
    • 200 成功
    • 404 找不到
  • 文档位于 RFC2616 第六章

用 curl 构造请求

curl 用法

curl 可以用来改请求动词、查询参数,还可以改第二部分的请求头、第三部分的请求内容…
  • 什么都可以改,请求的东西都可以由自己觉得
  • 只不过需要按照 http 的标准来写
前提条件:server 要处于开启的状态:node server.js 8888

例:curl -v http://localhost:8888

设置请求动词
  • -X POST
  • 例:curl -v -X POST http://localhost:8888 设置为post请求
  • 注意大小写
设置路径和查询参数
  • 直接在 url 后面加
  • 例:curl -v -X POST http://localhost:8888/xxx?id=xxx
  • 注:在 url 后添加 # 锚点是不会发送到服务器的
设置请求头
  • -H 'Name: Value' 或者 --header 'Name: Value'
  • 例:curl -v -X POST -H 'Accept: text/html' http://localhost:8888
设置请求体
  • -d '内容' 或者 --data '内容'
  • curl -v -X POST -H 'ABC: abc' -H 'Content-Type: text/plain;charset=utf-8' -d '请求体内容' http://localhost:8888
    在请求体中设置一个 ABC: abc,没有实际意义但是成立的。
    text/plain 表示上传的内容是纯文本,编码是 utf-8(中文),内容是'请求体内容'这5个字(每个字占2bytes)

0b43e21f65eb58c450bcbdc07e496ade.png
总结:可以使用 curl 随心所欲的构造一个请求

用 Node.js 读取请求

读取请求动词

  • request.method
    console.log('method:', request.method) // method: GET ...

读取路径

  • request.url 路径,带查询参数
    console.log('路径:', request.url) // 路径:/xxxx?wd=hihihi
  • path 纯路径,不带查询参数
  • query 只有查询参数

读取请求头

  • request.headers['Accept'] 读取请求头中的 Accept 值
    console.log("请求头:", request.headers) // 请求头:{ host:xxx, ???:???, ... }

读取请求体

  • 比较复杂,先不讲

用 Node.js 设置响应

设置响应状态码

  • response.statusCode = 200
  • 状态码可以任意设置,状态字符串会根据设置的状态码自动改变
  • 但是状态码是有统一的使用规则的,如 200 规定就是表示请求成功时返回的状态码,所以不要随意改变
  • 404 表示请求的网页不存在 。404 页面就是一个普通页面,是 Chrome 提供的,当访问页面不存在时提醒用户

设置响应头

  • response.setHeader("Content-Type", "text/html");

设置响应体

  • response.write("内容")
  • 可追加内容

curl 的作用是什么

不单单是用来测试 http 的请求和响应。
curl 可以完成 Chrome 的大多基本功能,但 curl 通过命令行执行,所以不具有可视化能力
  1. 下载图片curl 图片路径.jpg > xxx.jpg ( 在命令行开启的目录中,下载图片并重命名为 xxx )
curl https://i.loli.net/2020/07/15/Q2dnHSgxCcbfhZW.jpg > 3.jpg

dbd30e3025c04edce6166591226244eb.png
  1. 测试 请求和响应
  2. … curl 功能很强大,Chrome 的基本功能都可以实现,但不具有可视化

HTML / CSS / JS 的本质都是字符串

HTML / CSS / JS 的 本质都是字符串,不是文件
  • 本质上我们看到的网页,都是通过 html字符串 渲染的,html字符串 里面请求了 css字符串、js字符串
  • 从演示的 server.js 中就能体现这一点

console.log 调试大法

console.log(打印)这种调试方法,是在所有编程语言中都适用的
JS(console.log)、Java(print)、Python(print)、PHP(echo)… 语言/写法不一样,但原理相同
  • 把可能有问题的代码,打印看看
  • debug 就是在不断质疑自己的过程
  • 不要过分相信自己,而要相信 console.log() 可以告诉你对错
  • 程序员每天都在问自己错在哪里
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值