跨域
JSONP
使用<script>
標(biāo)簽不受同源策略影響的特性,作為Ajax傳輸技術(shù)稱為JSONP。
使用JSONP時(shí)贯莺,需要服務(wù)器返回一個(gè)實(shí)際內(nèi)容作為一個(gè)函數(shù)參數(shù)的函數(shù)執(zhí)行語句风喇。
//整個(gè)函數(shù)作為返回主體,實(shí)際的響應(yīng)主體
handleResponse(
//目標(biāo)需要的響應(yīng)主體
[1,2,{"buckle":"my shoe"}]
)
handleResponse()
的表達(dá)式在客戶端完成,通過<script>
標(biāo)簽使用JSONP后,在客戶端上會執(zhí)行handleResponse(data)
函數(shù)達(dá)到獲取數(shù)據(jù)的目的乖篷。
通常情況為了使用方便响驴,在URL中添加一個(gè)查詢參數(shù)來表示返回的執(zhí)行函數(shù)的函數(shù)名透且。
示例
//一個(gè)響應(yīng)處理函數(shù)
function handleResponse(response){
alert("You're at IP address " + response.id + ".");
}
var script = document.creatElement("script");
//在url中添加一個(gè)查詢參數(shù)指明響應(yīng)處理函數(shù)名稱
script.src = "http://XXX.XXX/XX?callback=handleResponse";
document.body.insertBefore(script,document.body.firstChild);
CORS跨域資源共享
CORS(Cross-Origin Resource Sharing)是一種跨域獲取資源的解決方案撕蔼。思想是使用自定義的http頭讓瀏覽器與服務(wù)器溝通,從而決定請求或響應(yīng)是否成功秽誊。(ie10以下不支持)
客戶端在發(fā)送請求的時(shí)候添加一個(gè)額外的頭部信息Origin
頭部鲸沮,內(nèi)容包含請求頁面的源信息(協(xié)議、域名和端口)锅论,服務(wù)器根據(jù)這個(gè)頭部信息來決定是否給予響應(yīng)讼溺。如果服務(wù)器認(rèn)為這個(gè)請求可以接受,就在Access-Control-Allow-Origin
頭部中發(fā)回相同的源信息最易。如果服務(wù)器返回的響應(yīng)沒有這個(gè)頭部或者頭部的源信息不匹配怒坯,瀏覽器就會駁回。
客戶端對于請求分為兩類藻懒,簡單請求和非簡單請求剔猿。
簡單請求
CORS對于簡單請求只是在頭信息中添加Origin
字段,這個(gè)字段說明本次請求來自哪個(gè)源嬉荆,即發(fā)送請求的頁面地址归敬。發(fā)送請求以后,瀏覽器會接收服務(wù)器的響應(yīng)鄙早,當(dāng)響應(yīng)成功時(shí)http碼200汪茧,在響應(yīng)頭中Access-Control-Allow-Origin
字段中出現(xiàn)請求頁面的地址,則請求頁面可以接收到來自服務(wù)器的信息,否則頁面不能獲取響應(yīng)的信息限番,但是實(shí)際信息已經(jīng)發(fā)送到瀏覽器舱污,由于同源策略的原因不可訪問。
Access-Control-Allow-Origin
該字段是必須的弥虐。它的值要么是請求時(shí)Origin
字段的值扩灯,要么是一個(gè)*
,表示接受任意域名的請求躯舔。
Access-Control-Allow-Credentials
字段表示是否允許發(fā)送Cookie驴剔。如果這個(gè)字段為true,表明可以接收cookie粥庄。xhr.withCredentials = true;
在瀏覽器上設(shè)置發(fā)送cookie;
Access-Control-Expose-Headers
字段表示獲取的響應(yīng)頭的其他字段丧失。
非簡單請求
非簡單請求是指請求方法為PUT
或DELETE
,或者Content-Type
為application/json
惜互。對于這樣的請求CORS會在正式請求之前發(fā)送一次預(yù)請求布讹。
預(yù)請求的方法是OPTIONS
琳拭,預(yù)請求的頭信息里包括Origin
Methods
Headers
三個(gè)字段。
? Access-Control-Allow-Origin
同簡單請求
? Access-Control-Allow-Methods
該字段必需描验,它的值是逗號分隔的一個(gè)字符串白嘁,表明服務(wù)器支持的所有跨域請求的方法。注意膘流,返回的是所有支持的方法絮缅,而不單是瀏覽器請求的那個(gè)方法。這是為了避免多次"預(yù)檢"請求呼股。
? Access-Control-Allow-Headers
該字段是一個(gè)逗號分隔的字符串耕魄,指定瀏覽器CORS請求會額外發(fā)送的頭信息字段。
如果瀏覽器否定了預(yù)請求彭谁,會返回一個(gè)正常的HTTP響應(yīng)吸奴,但是響應(yīng)頭中沒有任何CORS的信息。這時(shí)會觸發(fā)XMLHttpRequest
對象的onerror
方法缠局。
<script>
document.cookie = "This is Cookie";
var xhr = new XMLHttpRequest();
var url = 'http://localhost:8081/';
xhr.open('GET',url);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.onreadystatechange = function (){
if(xhr.readyState ===4){
if(xhr.status === 200){
var span = document.getElementById("span");
span.innerHTML = xhr.responseText;
alert(xhr.responseText);
}
}
};
//發(fā)送cookie
xhr.withCredentials = true;
xhr.send(null);
console.log(document.cookie);
</script>
var http = require('http');
var message = "This is massage";
http.createServer(function(req,res){
res.setHeader("Content-type","text/text");
res.setHeader("Access-Control-Allow-Origin","http://localhost:63342");
res.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE");
res.setHeader("Access-Control-Allow-Credentials",true);
//設(shè)置允許的請求頭中出現(xiàn)的字段
res.setHeader("Access-Control-Allow-Headers","X-Custom-Header");
res.writeHead(200);
res.write(message);
res.end(" end");
}).listen(8081);
WebSocket
WebSocket是一種通信協(xié)議则奥,使用ws://
和wss://
作為協(xié)議前綴,該協(xié)議是一種全雙工的協(xié)議狭园,http是一種半雙工協(xié)議读处。利用該協(xié)議不受同源策略限制的情況,可以使用該協(xié)議作為跨域通信的方式妙啃。