面试题-计算机网络-HTTP部分
前言
计算机网络2-HTTP部分的题目,是我根据Java Guide的面试突击版本V3.0再整理出来的,其中,我选择了一些比较重要的问题,并重新做出相应回答,并添加了一些比较重要的问题,希望对大家起到一定的帮助。
系列文章:
HTTP
-
URI和URL的区别
-
URI是统一资源标识符,可以理解为一个抽象的概念或者功能需求
-
URL是统一资源定位符,URL是URI的一种实现,用定位的方式实现唯一标识的功能
互联网中有许多的资源,如何获取一个具体的资源呢?
URI定义了一种获取资源的方式:如果想要获取资源,就需要给每个资源定义一种唯一的标识符,然后按照定义的唯一标识符去获取资源。URL代表了URI概念的一种具体实现。
-
-
HTTP方法
- GET:用于请求服务器发送某个资源
- HEAD:和GET方法类似,但是只会返回首部,不会返回实体
- PUT:用于请求服务器 使用请求主体部分中包含的内容 创建或修改 一个以请求URL 命名的文档。
- POST:用于向服务器发送数据
- DELETE:用于请求服务器删除 请求URL代表的资源文档
- OPTIONS:用于请求服务器 告知 支持的各项功能
-
HTTP的首部的分类
- 通用首部:客户端和服务器都可以使用的首部
- 请求首部:请求报文特有的首部
- 响应头部:响应报文特有的首部
- 实体首部:说明请求或者响应实体部分信息的首部
- 扩展首部:由程序开发者自定义的,但可以被HTTP程序接受并转发
-
说说你对cookie的认识
-
cookie中保存了 服务器为了识别用户身份产生的一些数据,存储在浏览器本地。
-
如果是同源的请求,浏览器会自动设置cookie请求头到请求中
-
同源的定义:URL中 协议,域名,端口都相同的才是同源
url 说明 是否跨域 http://www.cnblogs.com/a.js
http://www.a.com/b.js域名不同 是 http://www.a.com/lab/a.js
http://www.a.com/script/b.js同一域名下不同文件夹下的不同文件 否 http://www.a.com:8000/a.js
http://www.a.com/b.js不同端口 是 http://www.a.com/a.js
https://www.a.com/b.js不同协议 是 http://www.a.com/a.js
http://70.32.92.74/b.js域名和域名对应的ip 是 http://www.a.com/a.js
http://script.a.com/b.js三级域名不同 是
-
-
-
你了解跨域吗?跨域的请求是如何处理的?
上面问题4中介绍过同源的定义,只要不满足这个要求即为跨域。
现在的浏览器都实现了CORS标准,在CORS标准中,当发起一个跨域请求时:
如果是简单请求(GET HEAD POST 并且请求头中不能超出规定的几个字段),会在请求中加入一个Origin字段,Origin字段用来说明,本次请求的来源域(协议主机端口)
服务器如果允许访问,会在响应中加入一个头字段 Access-Control-Allow-Origin如果是非简单请求(简单请求之外的请求),浏览器会在请求之间加入一个预检请求,预检请求是一个OPTIONS请求.
请求头的核心还是Origin。
如果检查通过,可以访问,服务端会响应一些CORS字段,比如Access-Control-Allow-Origin;如果未通过,则会发送一个200响应,不包含任何CORS字段,浏览器发现后会抛出一个错误,然后用户可以通过XHR中的onerror回调函数捕获错误。
请求:OPTIONS /cors HTTP/1.1 Origin: http://api.bob.com Access-Control-Request-Method: PUT //必须字段,列出请求会使用哪些方法 Access-Control-Request-Headers: X-Custom-Header //可选字段,列出请求会额外发送的请求头 Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
CORS字段介绍:跨域资源共享 CORS 详解
-
HTTP 1.0和HTTP 1.1的主要区别是什么?
- 连接复用:1.0协议每个请求都是短连接,请求完毕后就会关闭TCP连接。TCP建立连接的过程成本较高,并且因为拥塞控制中的慢启动机制会影响新建立连接的发送速率,1.1版本中连接默认可以被多个请求复用了。
- 管道机制:1.1版本允许在未收到上一个请求的响应时就可以发送下一个请求,提高效率。
-
Session是什么?如何使用Session
HttpSession是javax.servlet.http中定义的接口,用来在服务端存储用户的信息,目的还是为了保持状态。
生成的SessionID可以存储在cookie中或者通过URL传递过来
-
Token机制和Session机制的区别?
- Session的机制:Session是保存在服务器内存中的数据,用户登录成功后,会返回一个SessionID,用户登录时,会携带SessionID,服务器根据SessionID拿到Session数据,从而得知用户是谁。
- Session的缺点:当需要部署多台服务器,就需要考虑Session如何在多台服务器同步以避免用户重复登陆问题。如果没有token,可以使用redis等缓存系统保存状态信息,多台服务器都从redis中查询信息,并且利用redis的过期失效机制来清除session。
token的核心是自含义,也就是说一旦成功登录,服务器返回给用户的token信息就包含了用户身份的信息(比如user_id),服务器不需要存储相关信息,当用户拿着token访问URL时,通过解密token就可以知道用户是谁。另外,token中还可以包含登录的时间戳,服务端在解密时同样可以判断该token是否过期。
-
你知道OAuth2.0协议吗?简单说说
OAuth2.0协议是一个授权机制,用来授权第三方应用,访问用户数据。
具体来说,第三方应用需要获取用户数据时,会跳转到授权页面,用户输入用户名和密码并且同意授权第三方应用后,系统会生成token给第三方应用,第三方应用使用这个token就可以获取相关的数据了。
那么token和密码有什么区别呢?
- token是有过期时间的,密码没有
- token可以由数据所有者随时撤销,如果拥有密码一般不允许撤销
- token是有权限范围的,密码一般代表更高或完整的权限
总结来看,OAuth2.0可以让应用获取授权的同时,又高度可控保证数据安全。
-
单点登录的实现方式(基于Session和cookie实现)
如果使用cookie和session来实现登录鉴权,那么需要考虑多个业务子系统之间的cookie和session同步的问题。
如果是同主域名不同子域名,可以这样同步cookie和session:
- sso服务校验用户名和密码通过后,将登录状态写入session,同时把sessionID写入cookie,并设置domain为主域名
- 因为主域名相同,所以业务子系统可以自动携带sso服务设置的cookie
- 使用spring session实现session共享即可
如果是跨域,可以这样设计:
- sso服务校验用户名和密码通过后,将sessionID写入cookie,设置domain为sso服务域名
- sso服务生成一个ST,跳转到app系统,将ST作为参数传递给app
- app拿到ST后,向sso服务校验ST是否有效
- 这一步存在的意义是:如果没有校验,直接把伪造的用户信息传递给app的回调地址,app也会认为登陆成功了。
- 校验通过,app将登录状态写入session,并设置app域下的cookie
总结:使用cookie的方式客户端实现比较轻松,不需要在所有的请求下都设置额外的请求头或者请求体中携带额外的sessionID数据。
-
单点登录的实现方式(基于JWT实现)
问题10中的设计思路是服务端保存登录状态信息,客户端也需要携带信息id来进行验证。
JWT或者Token的思路是服务端不保存登录信息,只要登陆成功,就把所有的相关信息传递给客户端保存,但是会设置一个过期时间。每次认证,客户端可以通过cookie(不能跨域)/请求头或者请求体中携带这些信息,服务端只需要计算是否被篡改以及过期时间即可。如果未被篡改以及没到过期时间即通过认证。
总结:
-
这种实现方式的优点是解放了服务端实现,方便扩展。
-
缺点是加重了客户端的实现复杂度并且增加了网络流量,同时服务端一旦下发token,在过期时间内无法撤销。
-
-
https部分待补充...
-
ftp http端口号
- FTP:端口号21;20端口和21端口的区别是,21端口用于传入控制指令;20端口为数据端口,在主动模式时使用,被动模式时由服务器和客户端协商一个数据传输端口。
- HTTP: 80是http协议的默认端口。
-
http状态码,502和504的区别
504:请求超时
- 向上游服务器写数据超时(写事件,比如connect事件)
- 上游服务器读数据超时(要么没发送过去,要么发送过去了还没处理,要么发送过去处理了没处理完)
502:bad gateway(连接出了错)
- 没发送成功
- 接收响应出错
-
http请求到相应的全过程
- 键入网址后,浏览器会和DNS服务进行交流,确定域名对应的ip地址
- 有了ip地址和端口号,就可以通过Socket建立连接
- 三次握手建立连接成功后,就开始传输数据(Http协议数据)
- 服务端解析HTTP协议数据,然后调用业务方法获取响应
- 把响应写入到socket发送会浏览器
- 浏览器解析这些响应,渲染成页面展示给用户