Symfony+Mercure与Angular16的SSE订阅认证问题求助
解决Angular 16订阅Mercure SSE的认证问题及ngx-sse-client参数不匹配问题
一、修复ngx-sse-client参数不匹配问题
- 检查安装版本:本地包与GitHub源码参数不一致,大概率是安装的版本非最新版,先确认当前版本:
npm list ngx-sse-client - 升级到最新版:
npm install ngx-sse-client@latest - 按当前版本类型定义调用:若升级后仍为2个参数,说明当前版本
stream方法通过第二个参数传递配置(包含headers),示例代码:import { SseClient } from 'ngx-sse-client'; constructor(private sseClient: SseClient) {} subscribeToMercure() { const authToken = 'your-jwt-token'; this.sseClient.stream('/mercure', { headers: { 'Authorization': `Bearer ${authToken}` } }).subscribe({ next: (event) => { // 触发前端缓存刷新逻辑 console.log('收到Mercure事件:', event); }, error: (err) => console.error('SSE订阅出错:', err) }); }
二、替代方案:自定义SSE服务(无需第三方库)
原生EventSource不支持自定义请求头,但可通过XMLHttpRequest模拟SSE,实现带认证头的订阅:
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class MercureSseService { subscribe(url: string, authToken: string): Observable<string> { return new Observable(observer => { const xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.setRequestHeader('Authorization', `Bearer ${authToken}`); xhr.setRequestHeader('Accept', 'text/event-stream'); xhr.setRequestHeader('Cache-Control', 'no-cache'); let lastPosition = 0; xhr.onprogress = () => { if (xhr.responseText) { const newData = xhr.responseText.slice(lastPosition); lastPosition = xhr.responseText.length; // 解析SSE格式数据 const events = newData.split('\n\n').filter(line => line.trim()); events.forEach(event => { const dataMatch = event.match(/^data:\s*(.*)$/m); if (dataMatch) { observer.next(dataMatch[1]); } }); } }; xhr.onerror = (error) => observer.error(error); xhr.onload = () => observer.complete(); xhr.send(); return () => xhr.abort(); }); } }
使用示例:
constructor(private mercureSse: MercureSseService) {} refreshCacheOnUpdate() { const mercureUrl = 'https://your-caddy-mercure-endpoint/.well-known/mercure'; const token = 'your-auth-token'; this.mercureSse.subscribe(mercureUrl, token).subscribe({ next: (data) => { // 执行缓存刷新操作,比如重新获取内容 console.log('收到更新通知,刷新缓存:', data); } }); }
三、Mercure认证的其他注意事项
- URL参数传递token:若不想自定义请求头,可将认证token放在URL参数中(Mercure支持
mercureAuthorization参数),示例:const mercureUrl = `https://your-caddy-mercure-endpoint/.well-known/mercure?mercureAuthorization=Bearer ${token}`; // 用原生EventSource订阅 const eventSource = new EventSource(mercureUrl); eventSource.onmessage = (event) => { /* 处理事件 */ }; - CORS配置:确保Caddy的Mercure插件允许前端域名跨域请求,且允许携带认证头或Credentials,Caddyfile配置示例:
your-domain.com { mercure { publish * subscribe * cors origin https://your-angular-app.com allow-credentials } }
内容的提问来源于stack exchange,提问作者AntiFTW
相关产品推荐
相关产品推荐

