js跨域資源共享
同源策略
同源策略是瀏覽器的一個安全功能,不同源的客戶端指令碼在沒有明確授權的情況下,不能讀寫對方資源。只要協議、域名、埠有任何一個不同,都被當作是不同的域。
跨域資源共享
1、CORS
基本思想:使用自定義的HTTP頭部讓瀏覽器與伺服器進行溝通,從而決定請求或相應是否成功,還是失敗。
CORS原理:只需要向響應頭header中注入Access-Control-Allow-Origin,這樣瀏覽器檢測到header中的Access-Control-Allow-Origin,則就可以跨域操作了。如果沒有這個頭部或者有這個頭部但源資訊不匹配,瀏覽器就會駁回請求。
基本流程:
對於簡單請求,瀏覽器直接發出CORS請求。具體來說,就是在頭資訊之中,增加一個Origin
欄位。
下面是一個例子,瀏覽器發現這次跨源AJAX請求是簡單請求,就自動在頭資訊之中,新增一個Origin
欄位。
GET /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
上面的頭資訊中,Origin
欄位用來說明,本次請求來自哪個源(協議 + 域名 + 埠)。伺服器根據這個值,決定是否同意這次請求。
如果Origin
指定的源,不在許可範圍內,伺服器會返回一個正常的HTTP迴應。瀏覽器發現,這個迴應的頭資訊沒有包含Access-Control-Allow-Origin
欄位(詳見下文),就知道出錯了,從而丟擲一個錯誤,被XMLHttpRequest
的onerror
回撥函式捕獲。注意,這種錯誤無法通過狀態碼識別,因為HTTP迴應的狀態碼有可能是200。
如果Origin
指定的域名在許可範圍內,伺服器返回的響應,會多出幾個頭資訊欄位。
Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8
上面的頭資訊之中,有三個與CORS請求相關的欄位,都以Access-Control-
開頭。
(1)Access-Control-Allow-Origin
該欄位是必須的。它的值要麼是請求時Origin
欄位的值,要麼是一個*
,表示接受任意域名的請求。
(2)Access-Control-Allow-Credentials
該欄位可選。它的值是一個布林值,表示是否允許傳送Cookie。預設情況下,Cookie不包括在CORS請求之中。設為true
,即表示伺服器明確許可,Cookie可以包含在請求中,一起發給伺服器。這個值也只能設為true
,如果伺服器不要瀏覽器傳送Cookie,刪除該欄位即可。
(3)Access-Control-Expose-Headers
該欄位可選。CORS請求時,XMLHttpRequest
物件的getResponseHeader()
方法只能拿到6個基本欄位:Cache-Control
、Content-Language
、Content-Type
、Expires
、Last-Modified
、Pragma
。如果想拿到其他欄位,就必須在Access-Control-Expose-Headers
裡面指定。上面的例子指定,getResponseHeader('FooBar')
可以返回FooBar
欄位的值。
需要注意的是,如果要傳送Cookie,Access-Control-Allow-Origin
就不能設為星號,必須指定明確的、與請求網頁一致的域名。同時,Cookie依然遵循同源政策,只有用伺服器域名設定的Cookie才會上傳,其他域名的Cookie並不會上傳,且(跨源)原網頁程式碼中的document.cookie
也無法讀取伺服器域名下的Cookie。
2、影象Ping
影象Ping跨域請求技術是使用<img>標籤。一個網頁可以從任何網頁中載入影象,不用擔心跨域不跨域。這也是線上廣告跟蹤瀏覽量的主要方式。也可以動態地建立影象,使用它們的onload和onerror事件處理程式來確定是否接收到了響應
動態建立影象經常用於影象Ping:影象Ping是與伺服器進行簡單、單向的跨域通訊的一種方式。 請求的資料是通過査詢字串形式傳送的,而響應可以是任意內容,但通常是畫素圖或204響應。通過影象Ping,瀏覽器得不到任何具體的資料,但通過偵聽load和error事件,它能知道響應是什麼時候接收到的
var img = new Image();
img.onload = img.onerror = function(){
alert("Done!");
};
img.src = "test.html?sum=a";
這裡建立了一個Image的例項,然後將onload和onerror事件處理程式指定為同一個函式。這樣無論是什麼響應,只要請求完成,就能得到通知。請求從設定src屬性那一刻開始,而這個例子在請求中傳送了一個sum引數
影象Ping有兩個主要的缺點,一是隻能傳送GET請求,二是無法訪問伺服器的響應文字。因此,影象Ping只能用於瀏覽器與伺服器間的單向通訊。
3、JSONP
JSONP:是JSON with padding(填充式JSON或引數式JSON)的簡寫,它由兩部分組成:回撥函式和資料。回撥函式是當響應到來時應該在頁面中呼叫的函式,回撥函式的名字一般是在請求中指定的,而資料就是傳入回撥函式中的JSON資料。
原理:如果一個頁面載入了一個外來的JS檔案,瀏覽器就會自動執行這個檔案中的程式碼。
JSONP是通過動態<script>元素來是用的,使用時可以為src屬性指定一個跨域URL。因為JSONP是有效的js程式碼,所以在請求完成後,即在JSONP相應載入到頁面中以後,就會立即執行。
JSONP之所以在開發人員中極為流行,主要是原因是它非常簡單易用。與影象Ping相比,它的優點在於能夠直接訪問相應文字,支援在瀏覽器與伺服器之間雙向通訊。例項:
前端:
<!DOCTYPE html>
<head>
<title>jsonp</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script>
//動態建立script標籤,並請求
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.src = src;
document.body.appendChild(script);
};
//在onload後,跨域請求
window.onload = function(){
addScriptTag('http://127.0.0.1:8080/jsonp?callback=test');
};
//回撥函式,必須為全域性,不然會報錯
function test(data){
alert(data.name);
};
</script>
</body>
</html>
sever:
//告訴Node.js引入http模組給該伺服器應用使用
var http = require('http');
//引入url模組解析url字串
var url = require('url');
//引入querystring模組處理query字串
var querystring = require('querystring');
//建立新的HTTP伺服器
var server = http.createServer();
//通過request事件來響應request請求
server.on('request',function(req, res){
var urlPath = url.parse(req.url).pathname;
var qs = querystring.parse(req.url.split('?')[1]);
if(urlPath === '/jsonp' && qs.callback){
res.writeHead(200,{'Content-Type':'application/json;charset=utf-8'});
var data = {
"name": "Monkey"
};
data = JSON.stringify(data);
var callback = qs.callback+'('+data+');';
res.end(callback);
}
else{
res.writeHead(200, {'Content-Type':'text/html;charset=utf-8'});
res.end('Hell World\n');
}
});
//監聽8080埠
server.listen('8080');
//用於提示我們伺服器啟動成功
console.log('Server running!');
缺點:
1.JSONP是從其他域中載入程式碼執行。如果其他域不安全,則可能會夾雜惡意程式碼。
2.要確定JSONP請求失敗並不容易。
3.只能使用get方式進行提交,不適合資料量較大請求。
4、Comet
Comet是一種伺服器向頁面推送資料的技術,兩種實現方式:長輪詢和流。
5、SSE
SSE是圍繞制度Comet互動推出的API或者模式,SSE API用於建立到伺服器的單向連線,伺服器通過這個連線可以傳送任意數量的資料。
6、Web Sockets(在獨立持久連線上提供全雙工、雙向通訊)
使用標準的HTTP伺服器無法實現,只有支援這種協議的專門伺服器才能正常工作。
相關文章
- 跨域資源共享跨域
- 跨域資源共享(CORS)跨域CORS
- 跨域資源共享CORS跨域CORS
- 跨域資源共享——CORS跨域CORS
- CORS 跨域資源共享CORS跨域
- CORS跨域資源共享CORS跨域
- 跨域資源共享配置錯誤跨域
- CORS(跨域資源共享)筆記CORS跨域筆記
- 詳解 CORS 跨域資源共享CORS跨域
- 跨域資源共享CORS詳解跨域CORS
- 跨域資源共享 CORS 詳解跨域CORS
- 詳解XMLHttpRequest的跨域資源共享XMLHTTP跨域
- 跨域資源共享(CORS)是什麼?跨域CORS
- 深入跨域問題(1) - 初識 CORS 跨域資源共享跨域CORS
- 跨域請求cookie資源共享詳解跨域Cookie
- 安全系列之:跨域資源共享CORS跨域CORS
- jsonp跨域資源引起CORBJSON跨域ORB
- OSS跨域資源共享(CORS)錯誤及排除跨域CORS
- 跨域資源共享 CORS 一些知識點跨域CORS
- 你所不知道的跨域資源共享(CORS)跨域CORS
- 跨域資源共享的各種方式(持續更新)跨域
- js資源跨域訪問的問題JS跨域
- 跨域資源共享 CORS(Cross-origin resource sharing)跨域CORSROS
- [CORS:跨域資源共享] W3C的CORS SpecificationCORS跨域
- Spring Boot中的跨域資源共享(CORS)處理Spring Boot跨域CORS
- 前端中的同源策略與三種跨域資源共享方法前端跨域
- php跨域共享sessionPHP跨域Session
- 跨域共享CORS詳解及Gin配置跨域跨域CORS
- 瀏覽器與伺服器通訊技術——跨域資源共享瀏覽器伺服器跨域
- 跨域是什麼?跨域請求資源有哪些方法?跨域
- 跨站資源共享CORS原理深度解析CORS
- 跨源通訊、跨域訪問跨域
- JSONProxy – 獲取跨域json資料工具JSON跨域
- 再也不學AJAX了!(三)跨域獲取資源 ② - JSONP & CORS跨域JSONCORS
- js -- 跨域問題JS跨域
- JSON形式跨域JSON跨域
- js跨域問題JS跨域
- ajax jsonp跨域JSON跨域