网络知识

浏览器如何定位一台服务器?

使用url统一资源定位符:protocal://hostname:port/path?query#hash

  • protocal: 协议,服务器根据不同的协议确定数据交换的格式和方式,常用的有httphttps
  • hostname: 主机名,可以是ip,也可以是域名;

    • ip:网络中每个终端的唯一编号;
    • 域名:和ip一一对应,方便记忆;
    • 域名和ip的关系:计算机是通过ip在网络上查找的另一台计算机,域名是方便人阅读和记忆。输入域名的时候,计算机会先去通过域名解析服务器(DNS)将域名转化成ip,再去网络中根据这个ip查找计算机。
  • port:端口号,服务器中有很多其它的应用,端口是用来定位使用服务器中的哪一个应用;

    • http: 默认端口80
    • https:默认端口443
  • path:路径,用于区分使用web服务器的哪个服务。
  • query:查询参数,用于向web服务器传递信息。

    url只支持ASCII字符,输入中文会被转义

  • hash:锚点,定位页面中的内容,唯一一个改变后浏览器不会重新访问服务器的值(不会刷新页面),可以用来做路由。

浏览器和服务器传输数据的格式是什么?

http是其中一种用来规定浏览器和服务器传输数据格式的协议。
http将浏览器和服务器之间的一次交互分为两个部分:

  • 请求request:客户端发生数据给服务器的过程
  • 响应response:服务器收到请求返回一个数据给客户端的过程

其实一个请求可以看做是一个规定了格式的特殊字符串,下面我们看看这个字符串是有什么组成的。

百度的网址为例,

请求request由请求头和请求体两个部分组成:

1. 请求头(request headers)

规定请求的请求方式,就是告诉服务器自己给什么格式的数据,以什么方式给,希望返回什么数据等。

GET /s?wd=abc HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Sec-Fetch-User: ?1
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.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PSTM=1563287690;

请求头又包括请求行和其它属性:

  • 请求行:请求头的第一行

    • 请求方法:GET、POST等
    • path:url中的path + search + has
    • 协议及版本号:HTTP/1.1
  • 其它属性:后面的数据以键值对的形式存储,可以自定义

    • Host: 主机名
    • Connection: 连接方式

2. 请求体(request body)

  1. 请求体就是浏览器要发送给服务器的数据,一般是服务器需要用到的业务数据。
  2. 请求头中也可以传递不同格式的数据,一般由请求头中的Content-Type属性来描述请求体中使用的格式。

    • 常见的格式:

      • application/x-www.form-urlencoded对应的数据格式:属性名=属性值&属性名=属性值
      • application/json对应的数据格式:{“属性名”:”属性值”, “属性名”:”属性值”}
      • multipart/form-data对应的数据格式:使用某个随机字符串作为属性之间的分隔符,通常用于文件上传。
      ------WebKitFormBoundaryD1o3TzulmXAIABD2
      Content-Disposition: form-data; name="image"; filename="xxx.png"
      Content-Type: image/png
      ------WebKitFormBoundaryD1o3TzulmXAIABD2--
      
响应response由响应头和响应体两个部分组成:

1. 响应头(response headers)

服务器根据请求头和请求体构建出来的数据,告诉客户端响应的状态,响应数据的格式等信息。

HTTP/1.1 200 OK
Content-Length: 24
Content-Type: text/plain; charset=UTF-8
Date: Mon, 03 Feb 2020 10:21:37 GMT

响应头又包括响应行和其它属性:

  • 请求行:请求头的第一行

    • 协议及版本号:HTTP/1.1
    • 状态码:对应不同的响应状态
    • 状态文本:用于描述状态码的文本
常见的状态码:
200: 请求成功。
301:资源永久重定向,告诉浏览器这个资源已经不在当前地址了,去其它地方取,其它地方的地址一般放在Location属性中。
302:资源临时重定向,告诉浏览器这个资源没有变化,自己去缓存中拿。
400:请求有问题,当前请求服务器无法识别。
403:服务器拒绝执行,可能是权限不够造成的,服务器不返回数据。
404:页面找不到,告诉浏览器这个地址不对,我这里找不到对应的资源。
500:服务器内部错误,表示是服务器处理程序出错。
502:网关错误,浏览器请求的地址可能还会进行一层网关的过滤,用来分发到不同的服务器,网关错误表示代理网关无法从上游服务器获取数据。
503:服务器过载,表示当前服务器处理不了那么多请求,拒绝当前浏览器发出的请求,一般会在响应头添加一个Retry-After属性。
504:网关超时,网关请求上游服务器一般会设置的一个时间限制,在规定时间内没有从上游服务器获取数据就会产生该错误信息。
  • 其它属性:后面的数据以键值对的形式存储,可以自定义

    • Server: web服务器类型,Apache、IIS等
    • Content-Type: 描述响应体中的数据格式

2. 响应体(response body)

服务器返回给客户端的业务数据

常见的数据格式有:

  • text/plain:普通的存文本。浏览器会原封不动的显示在页面上。
  • text/html:html文档,浏览器会将返回的数据解析成页面。
  • text/css:css代码,浏览器会根据返回数据渲染html页面。
  • text/javascript:js代码,浏览器会启动js引擎进行解析。
  • attachment:附件、浏览器看到该属性会自动下载服务器返回的数据。
  • 其它MIME类型

POST请求和GET请求的区别?

就协议的角度来讲是没有什么实质的区别,不管是那种请求都是由请求头和请求体组成的,只不过服务器会根据请求的方式不同去不同的地方读取业务数据。

服务器对于不同的请求方法做出的处理(不是绝对的,开发者可以自己处理)

  • GET请求:服务器遇到GET请求一般会去path中读取数据。
  • POST请求:服务器遇到POST请求一般会去请求体中读取数据。

浏览器对于不同请求做出的处理

  • GET请求会限制url大小,因此如果业务数据过大要使用POST请求。
  • POST请求只能通过表单的形式提交,在浏览器地址栏输入的url都是以GET的方式向服务器发送请求。

其它差异:

  1. GET请求会保留请求数据,利于用户做分享。
  2. GET请求的业务数据是放在url中的,一般带有用户信息的数据都不应该使用GET请求,防止被其它人偷窥,或者被用户自己分享出去。

什么是Ajax?

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

是浏览器提供给js的请求网络数据的API。

请求实例:

var xhr = new XMLHttpRequest(); //创建请求实例
// 监听请求变化的函数  
xhr.onreadystatechange = function (response) {
    if (xhr.readyState === 4 && xhr.status === 200) { //表示所有内容接受完毕,并且服务器返回的状态是请求成功
        console.log(xhr.responseText);
    }
}
xhr.open("GET", "https://api.binstd.com/shouji/query"); //配置请求
xhr.send(); //构建请求体,发送请求体

现在大部分的请求都使用fetch替代ajax。(fetch是es6提供的请求网络数据的新API,用promise封装的网络请求API。)

什么是跨域?

  1. 协议,域名,端口三者有一个不同就会造成跨域无法获取数据的问题;
  2. 跨域是浏览器为了提高安全性做的限制。只有在浏览器中才会发生的现象。服务器之间互相访问是不会出现跨域问题的;
  3. linkimgscript等含有src属性的标签也不会出现跨域问题;
  4. 解决跨域问题,有jsonp,后台设置运行跨域,iframe等方法;但是副作用最少,无需后台配合的就是自己写代理服务器。
代理服务器

服务器代理解决跨域问题思路:

  1. 出现跨域问题一般是请求不同域下的资源,请求相同域中的资源不会出现跨域问题。
  2. 自己编写一个服务器,将要发请求的页面放在该服务器下,再通过自己的服务器请求真实接口,将返回的数据回传给页面就可以解决跨域问题。

代理服务器的作用:你请求有跨域问题,我请求不会,我帮你请求再把数据返回给你。

举个例子:

环境:node v10.16.0,yarn 1.15.2

目录结构:

- demo.html
- proxy.js
  1. 在项目根目录打开cmd,运行命令:

    yarn init
    yarn add express
    yarn add request
    
  2. 新建demo.html文件,代码如下:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>测试跨域请求</title>
    </head>
    
    <body>
    <script>
        var xhr = new XMLHttpRequest(); //创建请求实例
        // 监听请求变化的函数  
        xhr.onreadystatechange = function (response) {
            if (xhr.readyState === 4 && xhr.status === 200) { //表示所有内容接受完毕,并且服务器返回的状态是请求成功
                console.log(JSON.parse(xhr.responseText));
            }
        }
        xhr.open("GET", "http://localhost:2020/api"); //配置请求
        xhr.send(); //构建请求体,发送请求体
    </script>
    </body>
    
    </html>
    
  3. 新建proxy.js文件,代码如下:

    var express = require('express'); //导入express模块
    var request = require('request'); //导入request模块
    
    var app = new express(); //创建express实例
    app.use(express.static('./')); //监听文件夹,获取静态资源
    app.listen(2020); //监听2020端口
    
    //监听api接口
    app.get('/api', function (req, res) {
        // 请求真实接口
        request('https://api.binstd.com/shouji/query', function(error,response,body){
            res.header('Content-Type', 'application/json;charset=utf-8');
            res.send(body); //返回数据
        })
    })
    
  4. 启动服务器,在cmd输入node proxy.js
  5. 打开浏览器,输入网址:http://localhost:2020/demo.html,查看控制台,现在就不会有跨域问题产生。

什么是三次握手?

客户端与服务器建立TCP/IP连接的准备阶段进行的三次交互被称为三次握手。

http协议是基于TCP/IP协议建立的数据传输协议,http定义的是数据收发双发的格式,TCP/IP协议定义的是数据接收时连接怎么建立。

过程:

  1. 客户端向服务器发送请求;
  2. 服务器接收请求,向客户端发送回应;
  3. 客户端接收回应;
为什么要进行三次握手?

为了建立一个可靠的连接,确保客户端和服务器都具备收发能力。

分析

假设只进行步骤1,客户端向服务器发送请求,客户端无法知道服务器真的能接到消息;

假设进行了步骤1,2,客户端知道服务器具备收数据的功能,服务器也知道客户端具备发数据的功能,但是服务器还不能确定客户端是否能收到数据;

所以要执行步骤3,这就是为什么一定要三次握手。

什么是四次挥手?

四次挥手是TCP/IP连接断开时候客户端和服务器进行的四次交互过程。

过程:

  1. 客户端发送中断请求,不再发送数据;
  2. 服务器接收中断请求,数据没发送完成,还可以发送数据;
  3. 服务器发送关闭连接请求 ,不可发送数据;
  4. 客户端确定关闭连接。

发完了,知道发完了,收完了,知道收完了

为什么要进行四次挥手?

为了确保在断开连接之前客户端和服务器的交互数据已经收发完毕。

分析:

  1. 客户端告诉服务器我要断开连接,不再发送数据;
  2. 服务器知道了客户端要断开请求,但是还有数据要发个客户端,告诉客户端先等我的数据发完再断开连接;
  3. 过了一会服务器数据发送完毕,服务器告诉客户端数据发完了,可以关闭连接了(此时服务端不再接收客户端消息);
  4. 客户端收到通知,关闭连接,不再接受服务端消息。完成整个断开连接过程。

作者:wcly

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被狗吃了的四年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值