如何用HTML SSE传递POST参数


How to pass POST parameters with HTML SSE?

我在这里有一个代码块,使用HTML 5 SSE - EventSource对象,它让php脚本推送更新到网页。但是,我对向脚本传递参数也很感兴趣。我该怎么做呢?

代码如下:

if(typeof(EventSource) !== "undefined")
    {
        var source = new EventSource("get_message.php");
        source.onmessage=function(event)
        {
            document.getElementById("message-window").innerHTML+=event.data + "<br>";
        };
    }
else
    {   
        document.getElementById("message-window").innerHTML="Sorry, your browser does not support server-sent events...";
     }

我能想到的最接近的方法是使用AJAX,如

$.post("get_message.php", {largest_id: 30}, function(data, status){ some function });

然而,我不确定如何编写这个jQuery ?

EventSource API不支持POST方法,但这并不意味着不能将SSE与POST一起使用。你不能使用EventSource API。
然而,也有其他的实现。一个例子是sse.js,它允许你指定一个有效负载,如果你需要,也可以指定头文件。sse.js应该是EventSource的直接替代品,例如:

var source = new SSE("get_message.php");
source.onmessage=function(event)
{
    document.getElementById("message-window").innerHTML+=event.data + "<br>";
};

为了使用POST方法,您只需要指定一个有效负载,例如:

var source = new SSE("get_message.php", {payload: 'Hello World'});

并且,由于它是一个完全兼容的填充,您可能可以这样做:

EventSource = SSE;
var source = new EventSource("get_message.php", {payload: 'Hello World'});
source.onmessage=function(event)
{
    document.getElementById("message-window").innerHTML+=event.data + "<br>";
};

我搜索了这个问题,找到了一个相关的解决方案与大家分享。

首先,您需要更改后端接口以支持POST请求。web页面通常会发起带有参数的POST请求。注意,您需要添加请求标头"Accept": "text/event-stream"。下面是一小段代码。处理消息解析和"重试"

const response = await fetch('http://127.0.0.1:8888/sse', {
        method: "POST",
        cache: "no-cache",
        keepalive: true,
        headers: {
            "Content-Type": "application/json",
            "Accept": "text/event-stream",
        },
        body: JSON.stringify({
            arg1: 1,
            arg2: 2
        }),
    });
    
    const reader = response.body.getReader();
    
    while (true) {
        const {value, done} = await reader.read();
        if (done) break;
    
        console.log('get.message', new TextDecoder().decode(value));
    }

提交POST请求来启动EventSource的缺点是重新连接到事件流,这是规范的一部分。由于浏览器必须能够重新建立到相同EventSource的连接,因此使用POST数据识别请求将意味着在每次重新连接尝试时再次发布相同的数据。根据最初的RFC 2616,这是POST请求的预期用途,为重新连接提供替代URL或单独的机制可能会使浏览器JavaScript的SSE实现过于复杂,并且当您使用POST查询来启动EventSource时也是一个实际的设计问题。

@blazonix使用SSE时必须区分发送和接收。

EventSource仅用于从服务器接收数据。要向服务器发送数据,必须使用常规的AJAX请求。

在我的库中,我可以重用相同的路径来发送和接收,但我区分调用者想要基于Accept头做什么:

  • Accept: text/event-stream -它是一个浏览器,想要启动事件流连接
  • Accept:任何其他类型-它是一个常规的非/AJAX调用GET或POST
示例java代码:GitHub

就这么简单。

$.post('your_url.php?your_parametre1=' + your_value1 + '&your_parametre2_likewise=' + your_value, function(data) {
alert(data); // whatever you echo from php file as a identifier of success or error.
});