网络

79. http 响应码 301 和 302 代表的是什么?有什么区别?

答:301,302 都是HTTP状态的编码,都代表着某个URL产生了转移。

区别:

  • 301 redirect: 301 代表永久性转移(Permanently Moved)。
  • 302 redirect: 302 代表暂时性转移(Temporarily Moved )。 

80. forward 和 redirect 的区别?

Forward和Redirect代表了两种申请转发形式:间接转发和间接转发。

间接转发形式(Forward),客户端和浏览器只收回一次申请,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该申请,在申请对象request中,保留的对象对于每个信息资源是共享的。

间接转发形式(Redirect)理论是两次HTTP申请,服务器端在响应第一次申请的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目标。

举个艰深的例子:

间接转发就相当于:“A找B借钱,B说没有,B去找C借,借到借不到都会把消息传递给A”;

间接转发就相当于:"A找B借钱,B说没有,让A去找C借"。

81. 简述 tcp 和 udp的区别?

  • TCP面向连贯(如打电话要先拨号建设连贯);UDP是无连贯的,即发送数据之前不须要建设连贯。
  • TCP提供牢靠的服务。也就是说,通过TCP连贯传送的数据,无差错,不失落,不反复,且按序达到;UDP尽最大致力交付,即不保障牢靠交付。
  • Tcp通过校验和,重传管制,序号标识,滑动窗口、确认应答实现牢靠传输。如丢包时的重发管制,还能够对秩序乱掉的分包进行顺序控制。
  • UDP具备较好的实时性,工作效率比TCP高,实用于对高速传输和实时性有较高的通信或播送通信。
  • 每一条TCP连贯只能是点到点的;UDP反对一对一,一对多,多对一和多对多的交互通信。
  • TCP对系统资源要求较多,UDP对系统资源要求较少。

82. tcp 为什么要三次握手,两次不行吗?为什么?

为了实现牢靠数据传输, TCP 协定的通信单方, 都必须保护一个序列号, 以标识发送进来的数据包中, 哪些是曾经被对方收到的。 三次握手的过程即是通信单方互相告知序列号起始值, 并确认对方曾经收到了序列号起始值的必经步骤。

如果只是两次握手, 至少只有连贯发起方的起始序列号能被确认, 另一方抉择的序列号则得不到确认。

83. 说一下 tcp 粘包是怎么产生的?

①. 发送方产生粘包

采纳TCP协定传输数据的客户端与服务器常常是放弃一个长连贯的状态(一次连贯发一次数据不存在粘包),单方在连接不断开的状况下,能够始终传输数据;但当发送的数据包过于的小时,那么TCP协定默认的会启用Nagle算法,将这些较小的数据包进行合并发送(缓冲区数据发送是一个堆压的过程);这个合并过程就是在发送缓冲区中进行的,也就是说数据发送进去它曾经是粘包的状态了。

②. 接管方产生粘包

接管方采纳TCP协定接收数据时的过程是这样的:数据到底接管方,从网络模型的下方传递至传输层,传输层的TCP协定解决是将其搁置接收缓冲区,而后由应用层来被动获取(C语言用recv、read等函数);这时会呈现一个问题,就是咱们在程序中调用的读取数据函数不能及时的把缓冲区中的数据拿进去,而下一个数据又到来并有一部分放入的缓冲区开端,等咱们读取数据时就是一个粘包。(放数据的速度 > 应用层拿数据速度) 

84. OSI 的七层模型都有哪些?

  1. 应用层:网络服务与最终用户的一个接口。

  2. 表示层:数据的示意、平安、压缩。

  3. 会话层:建设、治理、终止会话。

  4. 传输层:定义传输数据的协定端口号,以及流控和过错校验。

  5. 网络层:进行逻辑地址寻址,实现不同网络之间的门路抉择。

  6. 数据链路层:建设逻辑连贯、进行硬件地址寻址、过错校验等性能。

  7. 物理层:建设、保护、断开物理连贯。

85. get 和 post 申请有哪些区别?

  • GET在浏览器回退时是有害的,而POST会再次提交申请。
  • GET产生的URL地址能够被Bookmark,而POST不能够。
  • GET申请会被浏览器被动cache,而POST不会,除非手动设置。
  • GET申请只能进行url编码,而POST反对多种编码方式。
  • GET申请参数会被残缺保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET申请在URL中传送的参数是有长度限度的,而POST么有。
  • 对参数的数据类型,GET只承受ASCII字符,而POST没有限度。
  • GET比POST更不平安,因为参数间接裸露在URL上,所以不能用来传递敏感信息。
  • GET参数通过URL传递,POST放在Request body中。

86. 如何实现跨域?

形式一:图片ping或script标签跨域

图片ping罕用于跟踪用户点击页面或动静广告曝光次数。 
script标签能够失去从其余起源数据,这也是JSONP依赖的依据。 

形式二:JSONP跨域

JSONP(JSON with Padding)是数据格式JSON的一种“应用模式”,能够让网页从别的网域要数据。依据 XmlHttpRequest 对象受到同源策略的影响,而利用 <script>元素的这个凋谢策略,网页能够失去从其余起源动静产生的JSON数据,而这种应用模式就是所谓的 JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。所有,通过Chrome查看所有JSONP发送的Get申请都是js类型,而非XHR。 

毛病:

  • 只能应用Get申请
  • 不能注册success、error等事件监听函数,不能很容易的确定JSONP申请是否失败
  • JSONP是从其余域中加载代码执行,容易受到跨站申请伪造的攻打,其安全性无奈确保

形式三:CORS

Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的标准,提供了 Web 服务从不同域传来沙盒脚本的办法,以避开浏览器的同源策略,确保安全的跨域数据传输。古代浏览器应用CORS在API容器如XMLHttpRequest来缩小HTTP申请的危险起源。与 JSONP 不同,CORS 除了 GET 要求办法以外也反对其余的 HTTP 要求。服务器个别须要减少如下响应头的一种或几种:

Access-Control-Allow-Origin: *Access-Control-Allow-Methods: POST, GET, OPTIONSAccess-Control-Allow-Headers: X-PINGOTHER, Content-TypeAccess-Control-Max-Age: 86400

跨域申请默认不会携带Cookie信息,如果须要携带,请配置下述参数:

"Access-Control-Allow-Credentials": true// Ajax设置"withCredentials": true

形式四:window.name+iframe

window.name通过在iframe(个别动态创建i)中加载跨域HTML文件来起作用。而后,HTML文件将传递给请求者的字符串内容赋值给window.name。而后,请求者能够检索window.name值作为响应。

  • iframe标签的跨域能力;
  • window.name属性值在文档刷新后仍旧存在的能力(且最大容许2M左右)。

每个iframe都有包裹它的window,而这个window是top window的子窗口。contentWindow属性返回<iframe>元素的Window对象。你能够应用这个Window对象来拜访iframe的文档及其外部DOM。

<!--  下述用端口  10000示意:domainA 10001示意:domainB--><!-- localhost:10000 --><script> var iframe = document.createElement('iframe'); iframe.style.display = 'none'; // 暗藏 var state = 0; // 避免页面有限刷新 iframe.onload = function() { if(state === 1) { console.log(JSON.parse(iframe.contentWindow.name)); // 革除创立的iframe iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); } else if(state === 0) { state = 1; // 加载实现,指向以后域,避免谬误(proxy.html为空白页面) // Blocked a frame with origin "http://localhost:10000" from accessing a cross-origin frame. iframe.contentWindow.location = 'http://localhost:10000/proxy.html'; } }; iframe.src = 'http://localhost:10001'; document.body.appendChild(iframe);</script><!-- localhost:10001 --><!DOCTYPE html>...<script> window.name = JSON.stringify({a: 1, b: 2});</script></html>

形式五:window.postMessage()

HTML5新个性,能够用来向其余所有的 window 对象发送音讯。须要留神的是咱们必须要保障所有的脚本执行完才发送 MessageEvent,如果在函数执行的过程中调用了它,就会让前面的函数超时无奈执行。

下述代码实现了跨域存储localStorage

<!--  下述用端口  10000示意:domainA 10001示意:domainB--><!-- localhost:10000 --><iframe src="http://localhost:10001/msg.html" name="myPostMessage" style="display:none;"></iframe><script> function main() { LSsetItem('test', 'Test: ' + new Date()); LSgetItem('test', function(value) { console.log('value: ' + value); }); LSremoveItem('test'); } var callbacks = {}; window.addEventListener('message', function(event) { if (event.source === frames['myPostMessage']) { console.log(event) var data = /^#localStorage#(d+)(null)?#([Ss]*)/.exec(event.data); if (data) { if (callbacks[data[1]]) { callbacks[data[1]](data[2] === 'null' ? null : data[3]); } delete callbacks[data[1]]; } } }, false); var domain = '*'; // 减少 function LSsetItem(key, value) { var obj = { setItem: key, value: value }; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); } // 获取 function LSgetItem(key, callback) { var identifier = new Date().getTime(); var obj = { identifier: identifier, getItem: key }; callbacks[identifier] = callback; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); } // 删除 function LSremoveItem(key) { var obj = { removeItem: key }; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); }</script><!-- localhost:10001 --><script> window.addEventListener('message', function(event) { console.log('Receiver debugging', event); if (event.origin == 'http://localhost:10000') { var data = JSON.parse(event.data); if ('setItem' in data) { localStorage.setItem(data.setItem, data.value); } else if ('getItem' in data) { var gotItem = localStorage.getItem(data.getItem); event.source.postMessage( '#localStorage#' + data.identifier + (gotItem === null ? 'null#' : '#' + gotItem), event.origin ); } else if ('removeItem' in data) { localStorage.removeItem(data.removeItem); } } }, false);</script>

留神Safari一下,会报错:

Blocked a frame with origin “http://localhost:10001” from accessing a frame with origin “http://localhost:10000“. Protocols, domains, and ports must match.

防止该谬误,能够在Safari浏览器中勾选开发菜单==>停用跨域限度。或者只能应用服务器端转存的形式实现,因为Safari浏览器默认只反对CORS跨域申请。

形式六:批改document.domain跨子域

前提条件:这两个域名必须属于同一个根底域名!而且所用的协定,端口都要统一,否则无奈利用document.domain进行跨域,所以只能跨子域

在根域范畴内,容许把domain属性的值设置为它的上一级域。例如,在”aaa.xxx.com”域内,能够把domain设置为 “xxx.com” 但不能设置为 “xxx.org” 或者”com”。

当初存在两个域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的页面,因为其document.name不统一,无奈在aaa下操作bbb的js。能够在aaa和bbb下通过js将document.name = 'xxx.com';设置统一,来达到相互拜访的作用。

形式七:WebSocket

WebSocket protocol 是HTML5一种新的协定。它实现了浏览器与服务器全双工通信,同时容许跨域通信,是server push技术的一种很棒的实现。相干文章,请查看:WebSocket、WebSocket-SockJS

须要留神:WebSocket对象不反对DOM 2级事件侦听器,必须应用DOM 0级语法别离定义各个事件。

形式八:代理

同源策略是针对浏览器端进行的限度,能够通过服务器端来解决该问题

DomainA客户端(浏览器) ==> DomainA服务器 ==> DomainB服务器 ==> DomainA客户端(浏览器)

起源:blog.csdn.net/ligang2585116/article/details/73072868

87.说一下 JSONP 实现原理?

jsonp 即 json+padding,动态创建script标签,利用script标签的src属性能够获取任何域下的js脚本,通过这个个性(也能够说破绽),服务器端不在返货json格局,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。