共计 6657 个字符,预计需要花费 17 分钟才能阅读完成。
网络
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 的七层模型都有哪些?
-
应用层:网络服务与最终用户的一个接口。
-
表示层:数据的示意、平安、压缩。
-
会话层:建设、治理、终止会话。
-
传输层:定义传输数据的协定端口号,以及流控和过错校验。
-
网络层:进行逻辑地址寻址,实现不同网络之间的门路抉择。
-
数据链路层:建设逻辑连贯、进行硬件地址寻址、过错校验等性能。
-
物理层:建设、保护、断开物理连贯。
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, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-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 中进行了调用,这样实现了跨域。