79. http 響應(yīng)碼 301 和 302 代表的是什么鲜戒?有什么區(qū)別斤蔓?
答:301,302?都是HTTP狀態(tài)的編碼阻桅,都代表著某個(gè)URL發(fā)生了轉(zhuǎn)移。
區(qū)別:?
301?redirect:?301?代表永久性轉(zhuǎn)移(Permanently?Moved)兼都。
302?redirect:?302?代表暫時(shí)性轉(zhuǎn)移(Temporarily?Moved?)嫂沉。?
80. forward 和 redirect 的區(qū)別?
Forward和Redirect代表了兩種請(qǐng)求轉(zhuǎn)發(fā)方式:直接轉(zhuǎn)發(fā)和間接轉(zhuǎn)發(fā)扮碧。
直接轉(zhuǎn)發(fā)方式(Forward)趟章,客戶(hù)端和瀏覽器只發(fā)出一次請(qǐng)求,Servlet慎王、HTML尤揣、JSP或其它信息資源,由第二個(gè)信息資源響應(yīng)該請(qǐng)求柬祠,在請(qǐng)求對(duì)象request中北戏,保存的對(duì)象對(duì)于每個(gè)信息資源是共享的。
間接轉(zhuǎn)發(fā)方式(Redirect)實(shí)際是兩次HTTP請(qǐng)求漫蛔,服務(wù)器端在響應(yīng)第一次請(qǐng)求的時(shí)候嗜愈,讓瀏覽器再向另外一個(gè)URL發(fā)出請(qǐng)求,從而達(dá)到轉(zhuǎn)發(fā)的目的莽龟。
舉個(gè)通俗的例子:
直接轉(zhuǎn)發(fā)就相當(dāng)于:“A找B借錢(qián)蠕嫁,B說(shuō)沒(méi)有,B去找C借毯盈,借到借不到都會(huì)把消息傳遞給A”剃毒;
間接轉(zhuǎn)發(fā)就相當(dāng)于:"A找B借錢(qián),B說(shuō)沒(méi)有搂赋,讓A去找C借"赘阀。
81. 簡(jiǎn)述 tcp 和 udp的區(qū)別?
TCP面向連接(如打電話(huà)要先撥號(hào)建立連接);UDP是無(wú)連接的脑奠,即發(fā)送數(shù)據(jù)之前不需要建立連接基公。
TCP提供可靠的服務(wù)。也就是說(shuō)宋欺,通過(guò)TCP連接傳送的數(shù)據(jù)轰豆,無(wú)差錯(cuò)胰伍,不丟失,不重復(fù)酸休,且按序到達(dá);UDP盡最大努力交付骂租,即不保證可靠交付。
Tcp通過(guò)校驗(yàn)和斑司,重傳控制渗饮,序號(hào)標(biāo)識(shí),滑動(dòng)窗口陡厘、確認(rèn)應(yīng)答實(shí)現(xiàn)可靠傳輸抽米。如丟包時(shí)的重發(fā)控制特占,還可以對(duì)次序亂掉的分包進(jìn)行順序控制糙置。
UDP具有較好的實(shí)時(shí)性,工作效率比TCP高是目,適用于對(duì)高速傳輸和實(shí)時(shí)性有較高的通信或廣播通信谤饭。
每一條TCP連接只能是點(diǎn)到點(diǎn)的;UDP支持一對(duì)一,一對(duì)多懊纳,多對(duì)一和多對(duì)多的交互通信揉抵。
TCP對(duì)系統(tǒng)資源要求較多,UDP對(duì)系統(tǒng)資源要求較少嗤疯。
82. tcp 為什么要三次握手冤今,兩次不行嗎?為什么茂缚?
為了實(shí)現(xiàn)可靠數(shù)據(jù)傳輸戏罢, TCP 協(xié)議的通信雙方, 都必須維護(hù)一個(gè)序列號(hào)脚囊, 以標(biāo)識(shí)發(fā)送出去的數(shù)據(jù)包中龟糕, 哪些是已經(jīng)被對(duì)方收到的。 三次握手的過(guò)程即是通信雙方相互告知序列號(hào)起始值悔耘, 并確認(rèn)對(duì)方已經(jīng)收到了序列號(hào)起始值的必經(jīng)步驟讲岁。
如果只是兩次握手, 至多只有連接發(fā)起方的起始序列號(hào)能被確認(rèn)衬以, 另一方選擇的序列號(hào)則得不到確認(rèn)缓艳。
83. 說(shuō)一下 tcp 粘包是怎么產(chǎn)生的?
①. 發(fā)送方產(chǎn)生粘包
采用TCP協(xié)議傳輸數(shù)據(jù)的客戶(hù)端與服務(wù)器經(jīng)常是保持一個(gè)長(zhǎng)連接的狀態(tài)(一次連接發(fā)一次數(shù)據(jù)不存在粘包)看峻,雙方在連接不斷開(kāi)的情況下郎任,可以一直傳輸數(shù)據(jù);但當(dāng)發(fā)送的數(shù)據(jù)包過(guò)于的小時(shí)备籽,那么TCP協(xié)議默認(rèn)的會(huì)啟用Nagle算法舶治,將這些較小的數(shù)據(jù)包進(jìn)行合并發(fā)送(緩沖區(qū)數(shù)據(jù)發(fā)送是一個(gè)堆壓的過(guò)程)分井;這個(gè)合并過(guò)程就是在發(fā)送緩沖區(qū)中進(jìn)行的,也就是說(shuō)數(shù)據(jù)發(fā)送出來(lái)它已經(jīng)是粘包的狀態(tài)了霉猛。
②. 接收方產(chǎn)生粘包
接收方采用TCP協(xié)議接收數(shù)據(jù)時(shí)的過(guò)程是這樣的:數(shù)據(jù)到底接收方尺锚,從網(wǎng)絡(luò)模型的下方傳遞至傳輸層,傳輸層的TCP協(xié)議處理是將其放置接收緩沖區(qū)惜浅,然后由應(yīng)用層來(lái)主動(dòng)獲忍北纭(C語(yǔ)言用recv、read等函數(shù))坛悉;這時(shí)會(huì)出現(xiàn)一個(gè)問(wèn)題伐厌,就是我們?cè)诔绦蛑姓{(diào)用的讀取數(shù)據(jù)函數(shù)不能及時(shí)的把緩沖區(qū)中的數(shù)據(jù)拿出來(lái),而下一個(gè)數(shù)據(jù)又到來(lái)并有一部分放入的緩沖區(qū)末尾裸影,等我們讀取數(shù)據(jù)時(shí)就是一個(gè)粘包挣轨。(放數(shù)據(jù)的速度 > 應(yīng)用層拿數(shù)據(jù)速度)?
84. OSI 的七層模型都有哪些?
應(yīng)用層:網(wǎng)絡(luò)服務(wù)與最終用戶(hù)的一個(gè)接口轩猩。
表示層:數(shù)據(jù)的表示卷扮、安全、壓縮均践。
會(huì)話(huà)層:建立晤锹、管理、終止會(huì)話(huà)彤委。
傳輸層:定義傳輸數(shù)據(jù)的協(xié)議端口號(hào)鞭铆,以及流控和差錯(cuò)校驗(yàn)。
網(wǎng)絡(luò)層:進(jìn)行邏輯地址尋址焦影,實(shí)現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇车遂。
數(shù)據(jù)鏈路層:建立邏輯連接、進(jìn)行硬件地址尋址偷办、差錯(cuò)校驗(yàn)等功能艰额。
物理層:建立、維護(hù)椒涯、斷開(kāi)物理連接柄沮。
85. get 和 post 請(qǐng)求有哪些區(qū)別?
GET在瀏覽器回退時(shí)是無(wú)害的废岂,而POST會(huì)再次提交請(qǐng)求祖搓。
GET產(chǎn)生的URL地址可以被Bookmark,而POST不可以湖苞。
GET請(qǐng)求會(huì)被瀏覽器主動(dòng)cache拯欧,而POST不會(huì),除非手動(dòng)設(shè)置财骨。
GET請(qǐng)求只能進(jìn)行url編碼镐作,而POST支持多種編碼方式藏姐。
GET請(qǐng)求參數(shù)會(huì)被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會(huì)被保留该贾。
GET請(qǐng)求在URL中傳送的參數(shù)是有長(zhǎng)度限制的羔杨,而POST么有。
對(duì)參數(shù)的數(shù)據(jù)類(lèi)型杨蛋,GET只接受ASCII字符兜材,而POST沒(méi)有限制。
GET比POST更不安全逞力,因?yàn)閰?shù)直接暴露在URL上曙寡,所以不能用來(lái)傳遞敏感信息。
GET參數(shù)通過(guò)URL傳遞寇荧,POST放在Request body中举庶。
86. 如何實(shí)現(xiàn)跨域?
方式一:圖片ping或script標(biāo)簽跨域
圖片ping常用于跟蹤用戶(hù)點(diǎn)擊頁(yè)面或動(dòng)態(tài)廣告曝光次數(shù)砚亭。
script標(biāo)簽可以得到從其他來(lái)源數(shù)據(jù)灯变,這也是JSONP依賴(lài)的根據(jù)殴玛。
方式二:JSONP跨域
JSONP(JSON with Padding)是數(shù)據(jù)格式JSON的一種“使用模式”捅膘,可以讓網(wǎng)頁(yè)從別的網(wǎng)域要數(shù)據(jù)。根據(jù) XmlHttpRequest 對(duì)象受到同源策略的影響滚粟,而利用 <script>元素的這個(gè)開(kāi)放策略寻仗,網(wǎng)頁(yè)可以得到從其他來(lái)源動(dòng)態(tài)產(chǎn)生的JSON數(shù)據(jù),而這種使用模式就是所謂的 JSONP凡壤。用JSONP抓到的數(shù)據(jù)并不是JSON署尤,而是任意的JavaScript,用 JavaScript解釋器運(yùn)行而不是用JSON解析器解析亚侠。所有曹体,通過(guò)Chrome查看所有JSONP發(fā)送的Get請(qǐng)求都是js類(lèi)型,而非XHR硝烂。?
缺點(diǎn):
只能使用Get請(qǐng)求
不能注冊(cè)success箕别、error等事件監(jiān)聽(tīng)函數(shù),不能很容易的確定JSONP請(qǐng)求是否失敗
JSONP是從其他域中加載代碼執(zhí)行滞谢,容易受到跨站請(qǐng)求偽造的攻擊串稀,其安全性無(wú)法確保
方式三:CORS
Cross-Origin Resource Sharing(CORS)跨域資源共享是一份瀏覽器技術(shù)的規(guī)范,提供了 Web 服務(wù)從不同域傳來(lái)沙盒腳本的方法狮杨,以避開(kāi)瀏覽器的同源策略母截,確保安全的跨域數(shù)據(jù)傳輸。現(xiàn)代瀏覽器使用CORS在API容器如XMLHttpRequest來(lái)減少HTTP請(qǐng)求的風(fēng)險(xiǎn)來(lái)源橄教。與 JSONP 不同清寇,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求喘漏。服務(wù)器一般需要增加如下響應(yīng)頭的一種或幾種:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
跨域請(qǐng)求默認(rèn)不會(huì)攜帶Cookie信息,如果需要攜帶华烟,請(qǐng)配置下述參數(shù):
"Access-Control-Allow-Credentials":true
// Ajax設(shè)置"
withCredentials":true
方式四:window.name+iframe
window.name通過(guò)在iframe(一般動(dòng)態(tài)創(chuàng)建i)中加載跨域HTML文件來(lái)起作用陷遮。然后,HTML文件將傳遞給請(qǐng)求者的字符串內(nèi)容賦值給window.name垦江。然后帽馋,請(qǐng)求者可以檢索window.name值作為響應(yīng)。
iframe標(biāo)簽的跨域能力比吭;
window.name屬性值在文檔刷新后依舊存在的能力(且最大允許2M左右)绽族。
每個(gè)iframe都有包裹它的window,而這個(gè)window是top window的子窗口衩藤。contentWindow屬性返回<iframe>元素的Window對(duì)象吧慢。你可以使用這個(gè)Window對(duì)象來(lái)訪問(wèn)iframe的文檔及其內(nèi)部DOM。
? ??
方式五:window.postMessage()
HTML5新特性赏表,可以用來(lái)向其他所有的 window 對(duì)象發(fā)送消息检诗。需要注意的是我們必須要保證所有的腳本執(zhí)行完才發(fā)送 MessageEvent,如果在函數(shù)執(zhí)行的過(guò)程中調(diào)用了它瓢剿,就會(huì)讓后面的函數(shù)超時(shí)無(wú)法執(zhí)行逢慌。
下述代碼實(shí)現(xiàn)了跨域存儲(chǔ)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)?#([\S\s]*)/.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一下,會(huì)報(bào)錯(cuò):
Blocked?a?frame?with?origin?“http://localhost:10001”?from?accessing?a?frame?with?origin?“http://localhost:10000“.?Protocols,?domains,?and?ports?must?match.
避免該錯(cuò)誤间狂,可以在Safari瀏覽器中勾選開(kāi)發(fā)菜單==>停用跨域限制攻泼。或者只能使用服務(wù)器端轉(zhuǎn)存的方式實(shí)現(xiàn)鉴象,因?yàn)镾afari瀏覽器默認(rèn)只支持CORS跨域請(qǐng)求忙菠。
方式六:修改document.domain跨子域
前提條件:這兩個(gè)域名必須屬于同一個(gè)基礎(chǔ)域名!而且所用的協(xié)議,端口都要一致纺弊,否則無(wú)法利用document.domain進(jìn)行跨域牛欢,所以只能跨子域
在根域范圍內(nèi),允許把domain屬性的值設(shè)置為它的上一級(jí)域淆游。例如傍睹,在”aaa.xxx.com”域內(nèi),可以把domain設(shè)置為 “xxx.com” 但不能設(shè)置為 “xxx.org” 或者”com”稽犁。
現(xiàn)在存在兩個(gè)域名aaa.xxx.com和bbb.xxx.com焰望。在aaa下嵌入bbb的頁(yè)面,由于其document.name不一致已亥,無(wú)法在aaa下操作bbb的js熊赖。可以在aaa和bbb下通過(guò)js將document.name?=?'xxx.com';設(shè)置一致虑椎,來(lái)達(dá)到互相訪問(wèn)的作用震鹉。
方式七:WebSocket
WebSocket protocol 是HTML5一種新的協(xié)議俱笛。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信,同時(shí)允許跨域通訊传趾,是server push技術(shù)的一種很棒的實(shí)現(xiàn)迎膜。相關(guān)文章,請(qǐng)查看:WebSocket浆兰、WebSocket-SockJS
需要注意:WebSocket對(duì)象不支持DOM 2級(jí)事件偵聽(tīng)器磕仅,必須使用DOM 0級(jí)語(yǔ)法分別定義各個(gè)事件。
方式八:代理
同源策略是針對(duì)瀏覽器端進(jìn)行的限制簸呈,可以通過(guò)服務(wù)器端來(lái)解決該問(wèn)題
DomainA客戶(hù)端(瀏覽器) ==> DomainA服務(wù)器 ==> DomainB服務(wù)器 ==> DomainA客戶(hù)端(瀏覽器)
來(lái)源:blog.csdn.net/ligang2585116/article/details/73072868
87.說(shuō)一下 JSONP 實(shí)現(xiàn)原理榕订?
jsonp 即 json+padding,動(dòng)態(tài)創(chuàng)建script標(biāo)簽蜕便,利用script標(biāo)簽的src屬性可以獲取任何域下的js腳本劫恒,通過(guò)這個(gè)特性(也可以說(shuō)漏洞),服務(wù)器端不在返貨json格式轿腺,而是返回一段調(diào)用某個(gè)函數(shù)的js代碼两嘴,在src中進(jìn)行了調(diào)用,這樣實(shí)現(xiàn)了跨域族壳。