HTTP 全解
WWW = URL + HTTP + HTML
HTTP(协议):基于 TCP 和 IP 两个协议
URL(统一资源定位服务)的组成
协议+域名或IP+端口号+路径+查询参数+锚点
IP(Internet Protocal)
用来定位一台设备,每台设备都有自己独立的 IP,可以通过命令行 ipconfig
或者 ip138.com
查询 IP 地址。
几个特殊的 IP
- 127.0.0.1
- localhost 同意 hosts 指定为自己
- 0.0.0.0 不表示任何设备
端口:port
一台机器可以提供不同服务
- 要提供 HTTP 服务最好使用 80 端口
- 要提供 HTTPS 服务最好使用 443 端口
- 要提供 FTP 服务最好使用 21端口
一共有 65535 个端口(基本够用),总之:IP 和端口缺一不可。
域名
域名就是对 IP 的别称,baidu.com 对应的 IP 是 ping baidu.com,
qq.com 对应的 IP 是 ping qq.com
均衡负载:一个域名可以对应不同 IP,防止一台机器扛不住。
共享主机:一个 IP 可以对应不同域名。
在 cmder 中输入 nslookup baidu.com
可以得到百度的 IP。
当我们输入 baidu.com 会发生的过程:
- 浏览器会向电信/联通提供的 DNS 服务器询问 baidu.com 对应什么 IP。
- 电信/联通会回答一个 IP。
- 浏览器才会向对应 IP 的 80/443 端口发送请求,请求内容是查看 baidu.com 的首页。
为什么是 80 或者 443 端口?
因为服务器默认用 80端口提供 http 服务,默认用 443 提供 https 服务,开发者工具里可以看到具体的端口。
www.baidu.com
和 baidu.com
不是同一个域名,com
是顶级域名,baidu.com
是二级域名(俗称一级域名),www.baidu.com
是三级域名(俗称二级域名),域名和二级域名是父子关系。www
是多余的。
路径
可以做到请求不同的页面。
https://developer.mozilla.org/zh-CN/docs/Web/HTM
https://developer.mozilla.org/zh-CN/docs/Web/CSS
查询参数
请求同一个页面,得到不同内容。
www.baidu.com/s?wd=hi
www.baidu.com/s?wd=hello
锚点
请求同一个内容的不同位置。锚点看起来有中文,实际不支持中文,锚点是无法在 Network 面板看到的,因为锚点不会传给服务器。
请求和响应 & Node.js Server
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')
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)
复制代码
代码逻辑:
- 每次收到请求都会把中间的代码执行一遍
- 用
if else()
判断路径,并返回响应 - 如果是已知路径,一律返回 200
- 如果是为止路径,一律返回 404
Content-Type
表示内容的类型/语法response.write()
可以填写返回的内容response.end()
表示响应可以发给用户了
请求
请求动词 路径加查询参数 协议号/版本 (这是请求行)
Host:域名或 IP
Accept: text/html
Conctent-Type:请求体的格式
请求体(也就是上传内容)
三部分:请求行、请求头、请求体
请求动词有 GET POST PUT PATCH DELETE
请求体在 GET 请求中一般为空
复制代码
响应
协议号/版本 状态码 状态字符串
Content-Type:响应体的格式
响应体(也就是下载内容)
三部分:状态行、响应头、响应体
常见的状态码是考点
复制代码
AJAX
AJAX 的全部内容:用 JS 收请求和发响应。
AJAX 是浏览器上的内容,浏览器可以发请求,收响应。
window.HMLHttpRequest
是一个全局函数,也是一个构造函数,是用来创建 HMLHttpRequest
对象的。
每次修改 server.js 都要在中断中断开在保存,安装 node-dev,可以自动保存,方便开发。
进入这个连接 www.npmjs.com/package/nod… ,点击 github 链接
每一个 if else()
都是路由。
XMLHttpRequest 对象
以加载 CSS 为例
const request = new XMLHttpRequest(); //1.创建 XMLHttpRequest 对象
request.open("GET", "/style.css"); //2.调用对象的 open 方法
request.onreadystatechange = () => { //3.监听对象的 onreadystatechange 事件
console.log(request.readyState); // 下载完成,但不知道是成功 2xx 还是失败 4xx 5xx
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 300) {
const style = document.createElement("style");// 创建 style 标签
style.innerHTML = request.response; // 填写 style 内容
document.head.appendChild(style);// 插到头里面
} else {
alert("加载 CSS 失败");
}
}
};
request.send(); //4.调用对象的 send 方法(发送请求)
复制代码
readyState 状态值
- 0 未初始化,没有调用 open() 方法
- 1 启动,调用 open() 方法,没有调用 send()
- 2 发送,调用 send(),没有接收到响应
- 3 接收,已经接收到部分数据响应
- 4 完成,已经接收到全部响应数据,可以在客户端使用
图示如下:
JSON
JavaScript Object Notation( JS 对象标记语言)。不支持函数,不支持变量,也不支持引用。
const man = {
"name":"wbs",
"age":12,
"sex":"男"
};
复制代码
支持的数据类型:
- string 只支持双引号
- number 支持科学计数法
- bool: true 和 false
- null: 没有 undefinde
- object
- array
JSON.stringify()
可以把一个对象变成字符串。JSON.parse()
把字符串变成对象。
一般用 try catch
捕获错误