You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从SSE事件获取URL触发htmx的hx-get请求(Django+Channels)

解决方案:SSE事件触发模态框请求(Django+Channels+htmx)

方案1:htmx SSE扩展 + 自定义事件处理

利用htmx的SSE扩展触发的原生事件,提取事件中的URL并发起请求:

  1. 引入依赖并配置SSE订阅
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<script src="https://unpkg.com/htmx.org/dist/ext/sse.js"></script>

<!-- SSE订阅容器 -->
<div hx-ext="sse" sse-connect="/your-sse-endpoint/" sse-swap="order_complete"></div>
<!-- 模态框内容占位区 -->
<div id="modal-container"></div>
  1. 监听SSE消息事件,处理URL提取与请求
document.addEventListener('htmx:sseMessage', function(event) {
  if (event.detail.event === 'order_complete') {
    // 解析服务端发送的JSON数据(需确保服务端返回格式正确)
    const { url } = JSON.parse(event.detail.data);
    
    // 调用htmx API发起请求,填充模态框
    htmx.ajax('GET', url, {
      target: '#modal-container',
      swap: 'innerHTML',
      // 请求完成后显示模态框(以Bootstrap模态框为例)
      afterSwap: () => {
        new bootstrap.Modal(document.getElementById('rating-modal')).show();
      }
    });
  }
});
  1. 服务端SSE数据格式示例(Django-Channels)
import json
from channels.generic.websocket import AsyncWebsocketConsumer

class YourConsumer(AsyncWebsocketConsumer):
    async def send_order_complete_event(self, order_id):
        await self.send({
            'type': 'send_event',
            'event': 'order_complete',
            'data': json.dumps({'url': f'/orders/{order_id}/rating/'})
        })

方案2:带外交换(OOB)优化版(性能更优)

如果服务端可以直接生成模态框HTML,用OOB交换跳过额外请求,直接替换DOM:

  1. 前端仅需占位容器与SSE订阅
<div hx-ext="sse" sse-connect="/your-sse-endpoint/" sse-swap="order_complete"></div>
<div id="modal-container"></div>

<script>
// OOB交换完成后自动显示模态框
document.addEventListener('htmx:afterOobSwap', function(event) {
  if (event.detail.target.id === 'modal-container') {
    new bootstrap.Modal(document.getElementById('rating-modal')).show();
  }
});
</script>
  1. 服务端直接返回带OOB标记的HTML
from django.template.loader import render_to_string
import json

async def send_order_complete_event(self, order_id):
    # 渲染模态框模板
    modal_html = render_to_string('rating_modal.html', {'order_id': order_id})
    # 用OOB标记指定替换目标
    oob_content = f'<div id="modal-container" hx-swap-oob="innerHTML">{modal_html}</div>'
    
    await self.send({
        'type': 'send_event',
        'event': 'order_complete',
        'data': oob_content
    })

此方案减少一次HTTP请求,性能更优,适合服务端可直接生成前端内容的场景。


方案3:纯原生JavaScript方案(无需htmx)

如果不想依赖htmx,直接用原生EventSource处理SSE:

<div id="modal-container"></div>

<script>
const sse = new EventSource('/your-sse-endpoint/');

// 监听order_complete事件
sse.addEventListener('order_complete', (event) => {
    const { url } = JSON.parse(event.data);
    
    // 发起fetch请求加载模态框内容
    fetch(url)
        .then(res => res.text())
        .then(html => {
            document.getElementById('modal-container').innerHTML = html;
            new bootstrap.Modal(document.getElementById('rating-modal')).show();
        })
        .catch(err => console.error('模态框加载失败:', err));
});

// 处理SSE连接错误
sse.addEventListener('error', (event) => {
    console.error('SSE连接异常:', event);
    sse.close();
});
</script>

此方案逻辑直观,无需额外依赖,适合对htmx不熟悉的开发者。


内容的提问来源于stack exchange,提问作者Mikhail Skorikov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:27:23