Server Sent Events通过post方法

时间:2015-12-14 07:43:29

标签: json server-sent-events

我正在使用Html5 Server Sent Events。服务器端是Java Servlet。 我有一个想要传递给服务器的json数组数据。

var source = new EventSource("../GetPointVal?id=100&jsondata=" + JSON.stringify(data));

如果数组大小很小,服务器端可以获取查询字符串。 但是如果阵列大小很大。 (可能超过数千个字符),服务器无法获取查询字符串。 是否可以在new EventSource(...)中使用POST方法将json数组传递给服务器,以避免查询字符串长度限制?

5 个答案:

答案 0 :(得分:20)

不,SSE标准不允许POST。

(没有技术原因,据我所知 - 我认为只是设计师从未见过用例:它不仅仅是大数据,而且如果你想进行自定义身份验证方案有安全理由不把密码放在GET数据中。)

XMLHttpRequest(即AJAX)确实允许POST,因此一个选项是返回旧的long-poll / comet方法。 (我的书,Data Push Apps with HTML5 SSE详细介绍了如何做到这一点。)

另一种方法是预先POST所有数据,并将其存储在HttpSession中,然后调用SSE进程,该进程可以使用该会话数据。 (SSE确实支持cookie,因此JSESSIONID cookie应该可以正常工作。)

P.S。 standard没有明确说不能使用POST。但是,与XMLHttpRequest不同,没有参数可以指定要使用的http方法,也无法指定要发布的数据。

答案 1 :(得分:1)

虽然您不能使用EventSource API来这样做,但是没有技术原因导致服务器无法为POST请求实现。诀窍是让客户端发送请求。例如,This answer discusses sse.jsEventSource的替代品。

答案 2 :(得分:0)

或者,您可以从使用其他php定制的文件中读取数据

http://..../command_receiver.php?command=blablabla

command_receiver.php

<?php
$cmd = $_GET['command'];
$fh = fopen("command.txt","w");
fwrite($fh, $cmd);
fclose($fh);
?>

demo2_sse.php

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

//$a = $_GET["what"];
$time = microtime(true); //date('r');

$fa = fopen("command.txt", "r");
$content = fread($fa,filesize("command.txt"));
fclose($fa);

echo "data: [{$content}][{$time}]\n\n";
flush();
?>

并且EventSource包含在任意命名的html中,如下所示:

<!DOCTYPE html>
<html>
<body>
<h1>Getting server updates</h1>
var source = new EventSource("demo2_sse.php");
source.onmessage = function (event) {
        mycommand = event.data.substring(1, event.data.indexOf("]"));
       mytime = event.data.substring(event.data.lastIndexOf("[") + 1, event.data.lastIndexOf("]"));
}
</script>
</body>
</html>

答案 3 :(得分:0)

在这种情况下使事件源工作实在是太费力了,这涉及到一个端点,该端点使用户可以发布作业并接收作业令牌,而端点则可以使发布者侦听结果。

服务器需要存储令牌和与所述令牌相关联的单播流,这将只允许一个文本/事件流订阅它。

上载流数据或断开连接时,或者如果用户在其间对系统提出任何其他请求,或者用户会话期满,则必须销毁所述单播流。

一个更好的主意可能是使用Websocket连接,该连接允许用户发布信息并接收结果。

答案 4 :(得分:0)

EventSource API不支持POST方法,但这并不意味着您不能在POST中使用SSE。您只是不能使用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'});

而且,由于它是完全兼容的polyfill,您可以执行以下操作:

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