HTTP 笔记
IP
IP 全称 Internet Protocal
IP地址是分配给连接到使用Internet协议的网络的每个设备的一串数字。
- 约定两个事情
- 如何定位一台设备
- 如何封装数据报文,以跟其他设备交流
IP分为内网和外网
- 如何获取外网
- 租用宽带 → 链接路由器
- 路由器链接电信的服务器,拥有一个 外网IP
- 如果重启路由器,可能会重新分配一个 外网IP,即路由器没有固定的 外网IP
- 内网IP
- 路由器会创建一个内网,内网中的设备使用内网IP,一般这个IP的格式为192.168.xxx.xxx
路由器的功能
- 路由器拥有 外网IP 和 内网IP 两个IP
- 内网中的设备可以相互访问,但是无法直接访问外网,内网设备想要访问外网,必须经过路由器中转
- 外网中的设备可以相互访问,但是无法直接访问内网,外网设备想要访问内网,必须通过路由器
- 路由器也被称为 网关
几个特殊的IP
- 127.0.0.1 表示自己
- localhost 通过 hosts 指定为自己
- 0.0.0.0 不表示任何设备
端口 port
- 一台机器可以提供不同服务
- 要提供HTTP服务最好使用80端口
- 要提供HTTPS服务最好使用443端口
- 要提供FTP服务最好使用21端口
- 一共有65535个端口
IP和端口缺一不可
域名
域名是对IP的别称
可以用 ping baidu.com 查看 baidu.com对应什么IP
- 一个域名可以对应不同IP,这是均衡负载,防止一台机器顶不住
- 一个IP可以对应不同域名,这是共享主机
www.xxx.com和xxx.com不是同一个域名
- com是顶级域名
- xxx.com是二级域名(俗称一级域名)
- www.xxx.com是三级域名(俗称二级)
- 他们是父子关系
- 通过路径可以请求不同的页面 比如
https://developer.mozilla.org/zh-CN/docs/Web/HTML
https://developer.mozilla.org/zh-CN/docs/Web/CSS
可以使用开发者工具Network面板看两者的区别 - 通过查询参数可以查看同一个页面的不同内容 比如
www.baidu.com/s?wd=hi
www.baidu.com/s?wd=helle - 通过锚点可以查看同一个内容的不同位置 比如
https://developer.mozilla.org/zh-CN/docs/Web/CSS#参考书
https://developer.mozilla.org/zh-CN/docs/Web/CSS#教程
锚点无法在Network面板看到,因为锚点不会传给服务器,锚点看起来有中文,但不支持中文
域名和IP是通过DNS对应起来的
DNS
DNS (Domain Name System) 域名系统,是一个层次化、分散化的Internet连接资源命名系统。DNS维护着一个包含域名与对应资源例如IP地址的列表。
DNS最突出的功能是将易于记忆的域名(例如mozilla.org)翻译成为数字化的IP地址(例如151.106.5.172)。 这一从域名到IP地址的映射过程被称为DNS查询(DNS lookup),与之对应,DNS反向查询(rDNS)用来找到与IP地址对应的域名。
- 进入一个网页的过程
- 当输入一个xxx.com时,浏览器会向电信/联通提供的DNS服务器询问xxx.com对应什么IP,然后电信/联通回答一个IP,之后浏览器会向对应IP的 80/443端口 发送请求,请求查看xxx.com的首页
- 服务器默认用 80 提供 http 服务,默认 443 提供https 服务,可以在开发者工具里查看具体的端口
nslookup 命令
Nslookup(name server lookup)(域名查询):是一个用于查询Internet域名信息或诊断DNS服务器问题的工具。
nslookpu最简单的用法就是查询域名对应的IP地址
- 语法为: nslookup -qt=类型 目标域名
URL
统一资源定位系统(uniform resource locator;URL) 是因特网的万维网服务程序上用于指定信息位置的表示方法。
URL = 协议 + 域名/IP + 端口号 + 路径 + 查询字符串 + 锚点
一个URL由不同的部分组成,其中一些是必须的,而另一些是可选的,比如
http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
- http 是协议,表明了浏览器必须使用何种协议,通常是HTTP协议或者HTTPS(HTTP协议的安全版)
- www.example.com 是域名,表明正在请求哪个Web服务器
- :80 是端口,表示用于访问Web服务器上的资源的技术“门”。标准端口(HTTP为80,HTTPS为443)
- /path/to/myfile.html 是网络服务器上资源的路径,在Web的早期阶段,像这样的路径表示Web服务器上的物理文件位置,如今主要是由没有任何物理现实的Web服务器处理的抽象
- ?key1=value1&key2=value2 是提供给网络服务器的额外参数。这些参数是用 & 符号分隔的键/值对列表。在返回资源之前,Web服务器可以使用这些参数来执行额外的操作。每个Web服务器都有自己关于参数的规则,唯一可靠的方式来知道特定Web服务器是否处理参数是通过询问Web服务器所有者
- #SomewhereInTheDocument 是资源本身的另一部分的锚点,锚点表示资源中的一种“书签”,给浏览器现实位于该“书签”位置的内容的方向
以上URL内容来源于https://developer.mozilla.org/zh-CN/docs/Learn/Common_questions/What_is_a_URL
curl 命令
- 用 curl 可以发 HTTP 请求
- curl -v http://baidu.com
- curl -s -v – http://www.baidu.com
- url 会被 crul 工具重写,先请求DNS获得IP
- 进行TCP链接,TCP链接成功后,开始发送HTTP请求
- 请求内容
- 响应内容
- 响应结束后,关闭TCP连接
请求和响应
请求和响应产生在服务器和客户端(浏览器)之间,客户端发送一个请求到服务器的一个端口,服务器通过相同的端口对客户端产生一个响应
请求
- 两种方法发送请求
- 浏览器地址栏
- curl 命令 发请求的工具为 用户代理 英文名 User Agent
响应
要做出一个响应,Node.js有一个http模块可以做到
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号\n比如node 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请ctrl点击右边链接打开 http://localhost:' + port)
注意
- 这些代码是服务器代码,一般放在服务器上
- path 是不带查询参数的路径 /x
- query 是查询参数的对象形式 {a:‘1’}
- queryString 是查询参数的字符串形式 ?a=1
- pathWithQuery 是带查询参数的路径,一般不用
- request 是请求对象
- response 是响应对象
`` 这个里面的字符串可以回车
‘’ 这个里面的字符串回车要用\n
逻辑
- 每次收到请求都会把中间的代码执行一遍
- 用if else判断路径,并返回响应
- 如果是已知路径,一律返回200;如果是未知路径,一律返回400
- Content-Type 表示内容的 类型/语法 是决定文件类型的关键
- response.write() 可以填写返回的内容
- response.end() 表示响应可以发给用户了
HTTP
- 调试
Node.js,可以用log/debugger - 资料
Node.js文档 - 标准制定者
HTTP规格文档:RFC 2612
请求
- 格式
请求动词 路径加查询参数 协议名/版本 (请求行)
Host: 域名或IP
Accept: text/html
Content-Type: 请求体的格式 (这三行是请求头)
回车
请求体(也就是上传内容)- 请求动词有 GET / POST / PUT / PATCH / DELETE 等
- 请求体在GET请求中一般为空
响应
- 格式
协议名/版本 状态码 状态字符串 (状态行)
Content-Type: 响应体的格式 (响应头)
回车
响应体(也就是下载内容)
用 curl 构造请求
curl -v http://127.0.0.1:8888
- 设置请求动词
- curl -v -X POST http://127.0.0.1:8888
- 设置路径和查询参数
- 直接加在url的后面 比如curl -v http://127.0.0.1:8888/x
- 设置请求头
- curl -v -X POST -H ‘Accept:text/html’ http://127.0.0.1:8888
- -H ‘Name:value’ 或者 --header ‘Name:value’
- 设置请求体
- -d ‘内容’ 或者 --data ‘内容’
用 Node.js 读取请求
- 读取请求动词
request.method - 读取路径
request.url 路径,带查询参数
path 纯路径,不带查询参数
query 只有查询参数 - 读取请求头
request.headers[‘Accept’] - 读取请求体
用 Node.js 设置响应
- 设置响应状态码
respinse.statusCode=200 - 设置响应头
response.setHeader(‘Content-Type’,‘text/html’); - 设置响应体
response.write(‘内容’)
可追加内容