HTML5 – Server Sent Events
隨著Web應用程序的發展,實時通信變得越來越重要。愛掏網 - it200.com傳統的HTTP請求只能實現客戶端對服務器的請求和響應,但是在某些場景下,這種方式顯得力不從心,比如股票交易、多人在線游戲等需要實時更新的應用場景。愛掏網 - it200.com這時候,就需要用到Server Sent Events(SSE)。愛掏網 - it200.com
SSE使用HTTP協議,通過一種全新的方式允許服務器向客戶端推送數據,而不需要客戶端發出請求。愛掏網 - it200.com這種方式通常被用于實時更新:包括在線獨家新聞、股票報價、聊天室等。愛掏網 - it200.com
SSE主要是由JavaScript的EventSource對象發起。愛掏網 - it200.com代碼示例:
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
客戶端JavaScript通過使用EventSource對象與服務器協作的方式,來實現從服務器到客戶端的實時推送。愛掏網 - it200.com服務器發送更新時,事件源都會創建一個新的事件對象,該事件對象中包含了當前服務器發回的全部數據。愛掏網 - it200.com
服務器端如何實現SSE呢?服務器端代碼示例如下:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
data = "data: The server time is: " . date('H:i:s') . "\n\n";
echodata;
flush();
這段服務器端代碼會向客戶端發送當前服務器的時間(當做測試),并設置Content-Type為”event-stream”,表示這是一種SSE推送。愛掏網 - it200.com
服務器端的跨域問題
由于SSE使用的是HTTP協議,因此存在跨域問題。愛掏網 - it200.com在跨域請求的情況下,服務器需要設置Access-Control-Allow-Origin頭信息。愛掏網 - it200.com代碼示例如下:
header("Access-Control-Allow-Origin: *");
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
data = "data: The server time is: " . date('H:i:s') . "\n\n";
echodata;
flush();
這里的“*”表示接受任何跨域請求,也可以設置為具體的域名,以滿足不同的業務需求。愛掏網 - it200.com
事件類型
SSE支持三種事件類型:Message(一般事件)、Error(錯誤事件)和Close(關閉事件)。愛掏網 - it200.com
客戶端通過onmessage和onerror兩個事件處理程序來處理不同的事件類型。愛掏網 - it200.com
例如,在每一個消息之前,服務器會發送一個id事件:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
data = "id: " .id . "\n";
data .= "data: " .message . "\n\n";
echo $data;
flush();
在JavaScript中,可以導入這個事件,偵聽它,并進行處理:
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("sse.php");
source.addEventListener('id', function(event) {
console.log('Server sent an ID: ' + event.data);
}, false);
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
source.onerror = function(event) {
console.log('An error occurred and the connection was closed.');
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
瀏覽器支持情況
遺憾的是,IE瀏覽器不支持SSE,支持SSE的僅有Chrome、Firefox、Safari等主流現代瀏覽器。愛掏網 - it200.com但是,在不支持SSE的瀏覽器中,可以通過使用Polyfills來實現SSE的兼容。愛掏網 - it200.comPolyfills是一種JavaScript的常見技術,它可以在不支持某些特性的瀏覽器中模擬這些特性。愛掏網 - it200.com
Polyfills實現
Polyfills主要用于填充瀏覽器在實現某些特性時所遺漏的部分,比如SSE。愛掏網 - it200.com我們可以使用EventSource-js庫來實現Polyfills。愛掏網 - it200.com
<script src="https://cdn.jsdelivr.net/npm/event-source-polyfill/dist/eventsource.min.js"></script>
通過引入這個Polyfills庫,我們就可以在IE瀏覽器中使用SSE了。愛掏網 - it200.com
結論
Server Sent Events(SSE)是一種實現服務器向客戶端推送數據的Web API。愛掏網 - it200.com它使用HTTP協議,通過一種全新的方式允許服務器向客戶端推送數據,而不需要客戶端發出請求。愛掏網 - it200.comSSE可以廣泛應用于多種場景下,比如在線獨家新聞、股票報價、聊天室等需要實時更新的應用場景。愛掏網 - it200.com但是需要注意的是,由于IE瀏覽器不支持SSE,因此在不支持SSE的瀏覽器中,需要使用Polyfills來實現SSE的兼容。愛掏網 - it200.com