EventSource 需要添加header等信息
泛域名ssl证书 239元1年送1个月、单域名39元1年,Sectigo(原Comodo证书)全球可信证书,强大的兼容性,高度安全性,如有问题7天内可退、可开发票
加微信VX 18718058521 备注SSL证书
【腾讯云】2核2G4M云服务器新老同享99元/年,续费同价
一、原生EventSource
(一)定义:
MDN详解:Web API 接口参考>EventSource
(二)使用方式:
const eventSource = new EventSource('/api/test'); // 正常的EventSource,我们只关心以下三个事件 /* * open:订阅成功(和后端连接成功) */ eventSource.addEventListener("open", function(e) { console.log('open successfully') }) /* * message:后端返回信息,格式可以和后端协商 */ eventSource.addEventListener("message", function(e) { console.log(e.data) }) /* * error:错误(可能是断开,可能是后端返回的信息) */ eventSource.addEventListener("error", function(err) { console.log(err) // 类似的返回信息验证,这里是实例 err && err.status === 401 && console.log('not authorized') }) // 需要关闭了 eventSource.close()
Tip:我们值得注意的语法:new EventSource(url, configuration)
看一下MDN:
// 1、参数
(1) url:一个USVString ,它代表远程资源的位置
(2) configuration 可选:为配置新连接提供选项。
可选项是:withCredentials,默认为 false,指示 CORS 是否应包含凭据( credentials )。
// 2、返回值
一个新建的 EventSource 对象,如果指定了configuration, 则按其配置;否则,配置为合适的基本默认值。
发现要是更自定义的配置,比如加header什么的就不行了,所以我找了找合适的封装后的库,还真找到了:
github地址:EventSource polyfill
二、EventSource polyfil
(一)使用方式
import { EventSourcePolyfill } from 'event-source-polyfill'; const eventSource = new EventSourcePolyfill('/api/test', { headers: { 'X-Custom-Header': 'value' } }); /* * open:订阅成功(和后端连接成功) */ eventSource.addEventListener("open", function(e) { console.log('open successfully') }) /* * message:后端返回信息,格式可以和后端协商 */ eventSource.addEventListener("message", function(e) { console.log(e.data) }) /* * error:错误(可能是断开,可能是后端返回的信息) */ eventSource.addEventListener("error", function(err) { console.log(err) // 类似的返回信息验证,这里是实例 err && err.status === 401 && console.log('not authorized') }) // 需要关闭了 eventSource.close()
基本使用方法如此,此文只是工作中遇到使用,具体定义MDN写的很清楚了,如有疑问也可留言与我交流,最后的最后,希望能帮到大家解决业务问题!
遇到的问题:
这几天在vue项目中需要使用EventSource实现服务端推送,并且使用utf8和hmacsha1签名。在这个项目中用到了Moment.js和CryptoJs。Moment.js是用来获取UTC格式的本地时间。CryptoJs是用来进行utf8,hmacsha1加密和base64加密。
EventSource
是什么: EventSource的官方名称应该是 Server-sent events(缩写SSE)服务端派发事件,EventSource 基于http协议只是简单的单项通信,实现了服务端推的过程客户端无法通过EventSource向服务端发送数据。喜闻乐见的是ie并没有良好的兼容当然也有解决的办法比如 npm install event-source-polyfill。虽然不能实现双向通信但是在功能设计上他也有一些优点比如可以自动重连接,event IDs,以及发送随机事件的能力(WebSocket要借助第三方库比如socket.io可以实现重连。)
有什么用: 因为受单项通信的限制EventSource只能用来实现像股票报价、新闻推送、实时天气这些只需要服务器发送消息给客户端场景中。EventSource的使用更加便捷这也是他的优点。
解决方法:
// 实例化 EventSource 参数是服务端监听的路由。
if('EventSource' in window){ //判断当前浏览器是否支持sse let urlLink = 'http://172.16.0.88'; this.source = new EventSource(urlLink); this.source.onopen = function (event) { // 与服务器连接成功回调 if(this.source.readyState == 0){ console.log('sse通道未建立') } if(this.source.readyState == 1){ console.log('sse通道连接成功') } if(this.source.readyState == 2){ console.log('sse通道断开连接') } }; this.getEventListener(); //监听事件获取图片数据 this.source.onerror = function (error) { // 监听错误 console.log('错误') } }, //监听事件获取图片数据 getEventListener(){ let _that = this; _that.source.addEventListener('getDataList',function(e){ if(e.data != null){ let imgArr = []; imgArr = JSON.parse(e.data); _that.getUtcTime(); //获取UTC格式的本地时间 _that.getHas1(imgArr); //通过has1加密获取signture _that.getTest(imgArr); //获取图片 } }) }, //获取utc格式的本地时间(使用moment.js) getUtcTime(){ let localTime = new Date(); this.localTimeUtc = this.$moment(localTime).utc().format("ddd, DD MMM YYYY HH:mm:ss UTC"); }, //获取signture getHas1(obj){ let _that = this; if(obj != null){ obj.map(item=>{ let stringToSign = "GET\n\n\n\nx-amz-date:"+_that .localTimeUtc+"/n\thumbnail/"+item; let sign1 = _that.$cryptoJs.enc.utf8.parse(stringToSign); //使用cryptoJs,转本地时间为utf8格式 let result = _that.$cryptoJs.HmacSHA1(sign1,"PoKKHHTEST"); //使用cryptoJs,将utf8格式后的结果进行HmacSHA1加密 return _that.Signture.push(_that.$cryptoJs.enc.Base64.stringify(result)); //将HmacSHA1加密后的结果使用cryptoJs,进行base64加密 }) } }
二、如何使用EventSource在header里面传参呢?
那就要用到EventSourcePolyfill
首先,npm进行安装:
npm install event-source-polyfill
例子:
import {EventSourcePolyfill} from 'event-source-polyfill'; var es = new EventSourcePolyfill('/events', { headers: { 'Authorization': 'token', 'X-Custom-Header': 'value' } }); es.onopen = function(event) { console.log('连接成功') } es.onmessage = function(event) { // to to something… } es.onerror = function (error) { // 监听错误 console.log('错误') }