网络知识

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

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

  • protocal: 协议,服务器根据不一样的协议肯定数据交换的格式和方式,经常使用的有httphttps
  • hostname: 主机名,能够是ip,也能够是域名;css

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

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

    url只支持ASCII字符,输入中文会被转义
  • hash:锚点,定位页面中的内容,惟一一个改变后浏览器不会从新访问服务器的值(不会刷新页面),能够用来作路由。

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

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

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

微信截图_20200204092135.png

其实一个请求能够看作是一个规定了格式的特殊字符串,下面咱们看看这个字符串是有什么组成的。es6

百度的网址为例,web

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

1. 请求头(request headers)ajax

规定请求的请求方式,就是告诉服务器本身给什么格式的数据,以什么方式给,但愿返回什么数据等。express

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;

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

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

    • 请求方法: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<br/>
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. 客户端收到通知,关闭链接,再也不接受服务端消息。完成整个断开链接过程。