计算机网络之应用层面试题

1. 举例常见的应用层协议

  • HTTP协议(超文本传输协议)是一种最基本的客户机/服务器的访问协议。浏览器向服务器发送请求,而服务器回应相应的网页,用于从万维网服务器传输超文本到本地浏览器的传送协议。
  • FTP协议(文件传输协议)基于客户服务器模式,FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端,提供交互式的访问 面向连接 ,使用TCP/IP可靠的运输服务,主要功能:减少/消除不同操作系统下文件的不兼容性
  • DNS协议(域名解析协议)是一种用以将域名转换为IP地址的Internet服务。
  • MQ协议(消息队列)消息从发送者到接收者的方式也有两种。一种我们可以称为即时消息通讯,也就是说消息从一端发出后(消息发送者)立即就可以达到另一端(消息接收者),这种方式的具体实现就是我们已经介绍过的RPC(当然单纯的http通讯也满足这个定义);另一种方式称为延迟消息通讯,即消息从某一端发出后,首先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端。 这个容器的一种具体实现就是消息队列。

2. HTTP消息格式

  • 请求消息
    • 请求行
    • 请求头
    • 请求体
  • 相应消息
    • 相应行
    • 相应头
    • 相应体

3. HTTP协议中常见字段

注意:先逗号分割类型,再分号分割属性
Accept: audio/*; q=0.2, audio/basic

  • 表示客户端期望服务器返回的媒体格式。
  • 格式为audio/basic的优先级为1(如果没有q,默认q=1
  • 格式为audio/* 的优先级为0.2

注意:先逗号分割类型,再分号分割属性
Accept-Charset: utf8, gbk; q=0.6

  • 表示客户端期望服务器返回的内容的编码格式
  • 格式为uft8的优先级为1,
  • 格式为gbk的优先级为0.6

Content-Type: text/html; charset=utf8

  • Content-Type是服务器向客户端发送的头,代表内容的媒体类型和编码格式,是对Accept头和Accept-Charset头的统一应答。

Accept-Language:zh-CN,en-US;q=0.8,zh-TW;q=0.6

  • 表示客户端期望服务器返回的内容的语言。
  • 表示大陆简体中文优先,其次英语,再其次台湾繁体中文

Content-Language

  • 这个头字段内容是对Accept-Language的应答。服务器通过此字段告知客户端返回的Body信息的语言是什么。

Content-Length

  • 表示传输的请求/响应的Body的长度。GET请求因为没有Body,所以不需要这个头。
  • 携带Body的并且需要提前知道Body长度的请求/响应必须带上这个字段,以便对方可以方便的分辨出报文的边界,也就是Body数据何时结束。
  • 如果Body太大,需要边计算边传输,不到最后计算结束是无法知道整个Body大小的,这个时候可以使用http分块传输,这个时候也是不需要Content-Length字段的。

Content-Location

  • 当客户端请求的资源在服务器有多个地址时,服务器可以通过Content-Location字段告知客户端其它的可选地址。这个字段比较少见。

Date: Tue, 15 Nov 1994 08:12:31 GMT

  • 如果服务器没有缓存,那么Date就是响应的即时生成时间。
  • 如果服务器设有缓存,那么Date就是响应内容被缓存的时间。
  • 它必须符合规范里定义的特定格式,这种格式叫着HTTP-Date,不支持随意定义自己的时间格式。

Age: 86400

  • 表示资源缓存的年龄,也就是资源自缓存以来到现在已经过去了多少时间,单位是秒。

Expires: Thu, 01 Dec 1994 16:00:00 GMT

  • 服务器使用Expect头来告知对方资源何时失效。
  • 如果它的值等于Date头的值,就表示资源已经实效。

ETag

  • 资源标签,每个资源可以提供多个标签信息。
  • 它一般用来和下面的If-Match和If-None-Match配合使用,用来判断缓存资源的有效性。
  • 比较常见的标签是资源的版本号,比如可以拿资源数据的md5校验码作为版本号。

If-Match

  • If-Match的值一般是上面提到的ETag的值,它常用于HTTP的乐观锁。
  • 所谓HTTP乐观锁,是指客户端先GET这个资源得到ETag中的版本号,然后发起一个资源修改请求PUT|PATCH时通过If-Match头来指定资源的版本号,如果服务器资源满足If-Match中指定的版本号,请求就会被执行。
  • 如果不满足,说明资源被并发修改了,就需要返回状态码为412 Precondition failed 的错误。客户端可以选择放弃或者重试整个过程。

If-None-Match

  • 类似于If-Match,只是条件相反

Allow: GET, HEAD, PUT

  • 表示资源支持访问的HTTP Method类型。
  • 它是服务器对客户端的建议,告知对方请使用Allow中提到的Method来访问资源。

Connection: close
Connection: Keep-Alive

  • 当客户端和服务器需要协商连接的属性时,可以使用Connection头部。
  • 比较常用的一个值是close,用来通知对方在当前请求结束后关闭连接。

Expect: 100-continue

  • 用于请求发送之前向服务器询问许可。
  • 譬如要向服务器发送一个很大的文件而不确定是否超出限制,就可以在请求头里携带一个Expect头部
  • 如果服务器说不行,就会返回417 Expectation Failed错误告知客户端放弃。
  • 如果可以那就返回100 continue状态码告知客户端放马过来吧,于是客户端就会继续上传Body内容。

From

  • 该字段一般用来标记请求发起者的邮件地址,相当于给请求赋予一个责任人。

Host

  • RFC协议规定所有的HTTP请求必须携带Host头,即使Host没有值,也必须带上这个Host头附加一个空串,如果不满足,应用服务器应该抛出400 Bad Request。
  • 协议虽然这样规定,不过大部分网关或者服务器都比较仁慈,既然没有指定Host字段,那就给你默认加上一个。

Last-Modified

  • 标记资源的最近修改时间,它和Date比较类似,区别是Last-Modified代表修改时间,而Date是创建时间。

If-Modified-Since

  • 浏览器向服务器请求静态资源时,如果浏览器本地已经有了缓存,就会携带If-Modified-Since头,值为资源的Last-Modified时间,询问服务器该资源自从这个Last-Modified时间之后有没有被修改。
  • 如果没有修改过,就会向浏览器返回304 Not Modified通知浏览器可以放心使用缓存内的资源。
  • 如果资源修改过,那就像正常的GET请求一样,携带资源的内容返回200 OK。

If-Unmodified-Since

  • 类似于If-Modified-Since,意义相反。区别是当服务器资源条件不满足时,不是返回304 Not Modified,而是返回412 Precondition Failed。

Range: bytes=500-999

  • 支持断点续传的服务器必须处理Range头,它表示客户端请求资源的一部分时指定的请求字节范围。
  • 它是客户端向服务器发送的请求头。

Content-Range: bytes 21010-47021/47022

  • 针对上面的Range头,服务器响应客户端时也需提供相应的Content-Range头,表示传输的Body数据在整体资源块中的字节范围。
  • 表示该资源总共有47022字节,当前响应的内容是第21010-47021字节之间的内容。(从0开始)

If-Range

  • 在断点续传时,为确保连续2个请求之间服务器资源本身没有发生变化,需要If-Range头带上ETag的资源版本号。
  • 服务器资源根据这个版本号来判定资源是否改变了。
  • 如果没变,就返回206 Partial Content将部分资源返回。如果资源变了,那就相当于一个普通的GET请求,返回200 OK和整个资源内容。

HTTP/1.1 302 Temporary Redirect
Location: https://www-temp.example.org/

  • 服务器向客户端发送302跳转的时候,总会携带Location头信息,它的值为目标URL。

Max-Forwards

  • 用来限定网关或者代理的层数,也就是最大转发次数。
  • HTTP每经过一个网关或者代理层,Max-Forwards值就要减1。
  • 如果nginx接收到前端请求的时候Max-Forwards已经等于0,那么它就不应该再将请求转发到upstream指定的服务节点上。

Pragma: no-cache

  • 这个头是比较常见的,在前端开发模式下经常会加上这个头部。
  • 当网关收到一个带有这样请求的头部时,即使内部存在该请求资源的缓存并且有效也不可以直接发送给客户端,而必须转发给后面的upstream进行处理。
  • 不过如果真的所有的网关都遵循这个协议的话,攻击是很容易构造的,所以它一般仅用于开发模式,防止静态资源修改后前端得不到即时更新。

Referer

  • Referer是非常常用的头,它表示请求的发起来源URI,也就是当前页面资源的父页面。
  • 如果你从A页面跳转到B页面,那么请求B页面的请求头里面就会有Referer信息,它的值就是A页面的访问地址。
  • 通过追踪Referer,可得出资源页面之间复杂的跳转链,它非常适合用于网页的数据分析和路径优化。

Retry-After

  • 服务器升级时,来自客户端的请求会直接给予503(Service Unavailable)错误,通过在返回头里面加入Retry-After字段告知客户端何时服务可以恢复正常访问。
  • Retry-After的头可以是HTTP-Date,也可以是整数,表示多少秒后服务可以恢复正常访问。
  • 浏览器在拿到这个值之后可以考虑增加一个定时器在未来的某个时间进行重试。

Server

  • 用于返回服务器相关的软件信息,来告知客户端当前的HTTP服务是由某某软件提供的,可以看成是一种软件广告。
  • RFC协议里对这个头信息做了警告:暴露出服务器信息可能会导致黑客更易于攻击你的服务,建议谨慎使用。

User-Agent

  • 携带当前的用户代理信息,一般包含浏览器、浏览器内核和操作系统的版本型号信息。
  • 它和Server头是对应的,一个是表达服务器信息,一个是表达客户端信息。
  • 服务器可以根据用户代理信息统计出网页服务的浏览器、操作系统的使用占比情况,服务器也可以根据UA的信息来定制不一样的内容。

Transfer-Encoding: chunked

  • 传送Body信息时需要对Body数据采取何种变换。当HTTP对Body进行分块传送时,需要增加这样的头部信息才可以进行分块传送。其它类型目前没有遇到过。

Upgrade: HTTP/1.1

  • 服务器建议客户端升级传输协议。比如当客户端使用HTTP/1.0发送请求时,服务器就可以建议客户端升级到HTTP/1.1。

Via

  • 该字段用来标识一个请求经过的网关路由节点。如果这个请求经过了多个代理层,Via头部就会有多个网关信息。

ETag vs Last-Modified vs Expires

  • ETag一般携带的是资源的版本号,协议没有具体规定版本号是什么。它可以是资源的md5校验码,也可以是uuid,甚至可以是自增的数字,也可以是资源的修改时间。它的匹配方式是相等/不相等。因为服务器需要维护版本号,取决的版本号是什么,这可能是一个存储和计算的负担。
  • Last-Modified携带的资源的修改时间。它的匹配方式是大于/小于。如果是静态资源文件,一般就是操作系统记录的文件修改时间。
  • Expires是服务器告知客户端资源的过期时间。客户端缓存的资源在这个时间之后自动过期,而不需要非得向服务器确认一下是不是304 Not Modified才认为没过期。

Cache-Control

  • 这可能是HTTP头里面最复杂的一个头了。这个头既可以用于请求,也可以用于响应。在请求和响应的取值不一样,分别代表了不同的意思。
    • no-cache 如果no-cache没有指定值,那就表示不允许缓存。对于请求来说,服务器不得使用缓存内容直接返回。对于响应来说,客户端不得缓存响应的资源内容。如果no-cache指定了值,那就表示值对应的头信息不得使用缓存,其它的信息还是可以缓存的。告知对方我只要新鲜刚出浴的数据。
    • no-store 告知对方不要持久化请求/响应数据到其它地方,这种信息是敏感的,要保持它的易失性。告知对方记在心里(memory)就行,别写在纸上(disk)。
    • no-transform 告知对方不要转换数据。比如客户端上传了raw图像数据,服务器一般都会选择性压缩图像数据进行存储。no-transform告知对方保留原始数据信息,不要进行任何转换。告知对方不要乱动我发过来的东西。
    • only-if-cached 用于请求头,告知服务器只要那些已经缓存的内容,不要去reload。如果没有缓存内容就返回504 Gateway Timeout错误。表示客户端不想太麻烦服务器,有就给,没就算了。
    • max-age 用于请求头。限制缓存内容的年龄,如果超过max-age年龄的,需要服务器去reload内容资源。这叫客户端的年龄歧视。
    • max-stale 用于请求头。客户端允许服务器返回缓存已过期的资源内容,但是限定了最大过期时间。表示客户端虽然很宽容,那是也是有限度的。
    • min-fresh 用于请求头。客户端限制服务器不要那些即将过期的资源内容。就好比我们去超市买牛奶,如果牛奶快过期了虽然还在保质期内咱们也就不会考虑。
    • public 用于响应头。表示允许客户端缓存响应信息,并可以给别人使用。比如代理服务器缓存静态资源供所有代理用户使用。
    • private 用于响应头。表示仅允许客户端缓存响应信息给自己使用,不得分享给别人。这样是为了禁止代理服务器进行缓存,而允许客户端自己缓存资源内容。意思是你个人留着用就行,别借给别人用。

4. http常见的返回码

  • 200 :请求成功。一般用于GET与POST请求
  • 204(No Content): 无内容。服务器成功处理,但未返回内容。使用惯例是,在 PUT 请求中进行资源更新,但是不需要改变当前展示给用户的页面,那么返回 204 No Content。如果创建了资源,则返回 201 Created 。如果应将页面更改为新更新的页面,则应改用 200
  • 206(Partial Content):是对资源某一部分的请求,服务器成功处理了部分GET请求,响应报文中包含由Content-Range指定范围的实体内容。
  • 301(Moved Permanently):永久性重定向。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
  • 302:临时性重定向。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
  • 304(Not Modified):未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
  • 400(Bad Request):客户端请求报文中存在语法错误,服务器无法理解。
  • 401(Unauthorized):请求要求用户的身份认证,通过HTTP认证(BASIC认证,DIGEST认证)的认证信息,若之前已进行过一次请求,则表示用户认证失败
  • 403(Forbidden):服务器理解请求客户端的请求,但是拒绝执行此请求
  • 404(Not Found):服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面。也可以在服务器拒绝请求且不想说明理由时使用
  • 500(Internal Server Error):服务器内部错误,无法完成请求,也可能是web应用存在bug或某些临时故障
  • 503(Service Unavailable):由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中

5. Get和Post的区别

  • GET方法请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据
  • POST方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用
  • 本质上都是TCP链接,并无差别但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中会体现出一些区别
  • 参数
    • GET的参数是以查询字符串出现在URL中,因为URL只支持ASCII码,所以中文参数需要被编码
    • POST也可以在URL上加参数,但它也可以将参数存储到实体主体中去
    • URL上的参数长度有限制,不同的浏览器限制不同,实体主体中的参数没有长度限制
  • 安全
    • POST 比 GET 安全,因为数据在地址栏上不可见
    • 然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文
  • 数据包
    • 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据)
    • 对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok,当然并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次
  • 幂等性
    • 同样的请求执行一次和执行多次的效果是一样的。服务器的状态也是一样的。即执行多次也不会产生数据错误。
    • 正常实现的条件下,GET、HEAD、PUT、DELETE等方法都是幂等的,而POST方法不是

6. http1.1与http2.0的区别

http1.0

  • 一个请求一个TCP连接

http1.1

  • 支持长连接,一个TCP连接内可以发送多个请求
  • 支持管道网络传输,以前发一个HTTP请求后,收到HTTP响应后才可以再发第二个HTTP请求,现在可以发送完第一个HTTP请求后不需要等收到响应就可以发送第二个HTTP请求。
  • 但是服务端必须按照接收到的客户端请求的先后顺序依次返回响应结果,以保证客户端能够区分每次请求的响应内容。(所以可能会有队头阻塞的问题)

http2.0

  • 支持头部压缩,利用HPACK算法:在客户端和服务器端同时维护一张头信息表(静态表和动态表),将头部字段都会存入这个表,生成索引号,以后就不发送同样字段了,只发送索引号。提高了速度
  • 数据采用二进制格式传输。头信息帧+数据帧,增加了数据传输的效率
  • 一个连接中并发多个请求或回应,而不用按照顺序一一对应,顺序通过编号来保证。
  • 服务器推送:服务器不再是被动的响应,比如浏览器请求html的时候,服务器不光响应html页面,而且提前把需要用的js、css等资源主动发给客户端

7. http2.0的缺陷

  • 多个HTTP请求共用一个TCP连接。如果前面一个包(http请求)丢失。超时重传机制会导致后面的http请求都必须等待这个丢失的包被重传回来。

8. 为什么需要url编码

  • 我们的http协议中的参数传输是 key=value 这种键值对形式的
  • 如果需要传多个参数,就需要用 & 符号对键值对进行分割
  • 如 name1=value1&name2=value2&name3=value3,这样服务端在收到这种字符串的时候,会用&分割出每一个参数,然后再用=来分割出参数值;
  • 但是如果value中包含&或者=这种特殊字符怎么办,比如name1= value1,其中value1=va&lu=e1字符串没那么在传输过程中,就变成了 name1=va&lu=e1,我们的本意是一个键值对,但是服务端会解析成两个键值对,这样就产生了歧义。
  • 如何解决上述问题带来的歧义,就是对参数进行url编码
  • 而且url采用ASCII传输,这也就是不能在Url中包含任何非ASCII字符,例如中文。

9. 断点续传的原理

  • 要实现断点续传的功能,通常都需要客户端记录下当前的下载进度,并在需要续传的时候通知服务端本次需要下载的内容片段。
  • HTTP1.1协议(RFC2616)中定义了断点续传相关的HTTP头 Range和Content-Range字段,一个最简单的断点续传实现大概如下:
  • 客户端下载一个1024K的文件,已经下载了其中512K
  • 网络中断,客户端请求续传,因此需要在HTTP头中申明本次需要续传的片段: Range:bytes=512000- 这个头通知服务端从文件的512K位置开始传输文件
  • 服务端收到断点续传请求,从文件的512K位置开始传输,并且在HTTP头中增加:Content-Range:bytes 512000-/1024000 并且此时服务端返回的HTTP状态码应该是206,而不是200。
  • 但是在实际场景中,会出现一种情况,即在终端发起续传请求时,URL对应的文件内容在服务端已经发生变化,此时续传的数据肯定是错误的。如何解决这个问题了?显然此时我们需要有一个标识文件唯一性的方法。在RFC2616中也有相应的定义,比如实现Last-Modified来标识文件的最后修改时间,这样即可判断出续传文件时是否已经发生过改动。同时RFC2616中还定义有一个ETag的头,可以使用ETag头来放置文件的唯一标识,比如文件的MD5值。

10. 什么是CSRF

  • 跨域请求伪造
  • 由于请求是从用户的浏览器发出,便能自动带上用户的cookie发送到服务器。
  • 此时如果服务器未做针对跨域的配置,又或者图省事而允许了大部分的http方法跨域,那么此时服务器并不能识别这个请求是否是伪造的。
  • 此时服务器将会按照请求进行处理,那么就极有可能造成损失。

原理

  • 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
  • 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
  • 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
  • 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  • 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
  • 总结:攻击者盗用了你的身份,以你的名义发送恶意请求。

11. 如何预防CSRF

  • 使用验证码
  • 验证http Referer http头中的referer字段
  • 在表单中加hash验证

12. 什么是XSS

  • 跨站脚本攻击
  • 攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
  • 可以窃取 Cookie 信息。恶意 JavaScript 可以通过“document.cookie”获取 Cookie 信息,然后通过 XMLHttpRequest 或者 Fetch 加上 CORS 功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie 信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。
  • 可以监听用户行为。恶意 JavaScript 可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送 到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。
  • 可以通过修改 DOM伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。
  • 还可以在页面内生成浮窗广告,这些广告会严重地影响用户体验。

13. XSS的解决办法

  • 输入过滤:URL 参数,POST参数都需要验证,对每一个用户的输入或者请求首部,都要进行过滤
  • 安装应用防火墙。

14. 什么是中间人攻击

  • 中间人攻击,它其实就是通过拦截正常的网络通信数据,进行数据篡改和嗅探,而通信双方却不知情。SMB会话劫持,DNS欺骗和ARP欺骗等攻击都属于典型的中间人攻击。
  • 中间人攻击基本上都利用了网络协议设计的漏洞,在防御上较为困难,但是大多数中间人攻击都会先监听目标主机网络流量,做好对目标主机的欺骗工作,因此防止被欺骗是非常重要的,因此我们应该使用如下的防御措施:
  • 使用静态ARP,绑定MAC地址和IP地址映射,防止ARP攻击。
  • 安装ARP防火墙
  • 将重要的域名和IP地址的映射写到系统HOST文件,保护好HOST文件不被恶意篡改。
  • 使用污染小的DNS服务器。
  • 使用自己可信赖的网络代理,将自己所有的网路数据加密传输到安全的代理中去。

15. 什么是https

  • 用户通过浏览器请求https网站。服务器收到请求,选择浏览器支持的加密和hash算法,同时返回数字证书给浏览器,数字证书中包括颁发机构,网站、公钥、证书有效期等信息
  • 浏览器对证书的内容进行校验,如果有问题,则会有一个提示警告。否则就生成一个随机数X,同时使用证书中的公钥对这个随机数X进行加密,并且发送给服务器
  • 服务器收到之后,使用私钥解密,得到随机数X,然后使用X对网页内容进行对称加密,返回给浏览器
  • 浏览器则使用X和之前约定好的加密算法(对称加密)进行解密,得到最终的网页内容
    https服务器默认端口时443
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值