15

I've got a block of code here that uses HTML 5 SSE - the EventSource object, which lets a php script push updates to the webpage. However, I'm interested in also passing parameters to the script. How can I do that?

Here's the code:

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...";
     }

The closest thing I can think of is to use AJAX, as in

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

However, I'm not sure how to write the jQuery for this?

ChiraChan
  • 15
  • 4
blazonix
  • 393
  • 2
  • 5
  • 15
  • 1
    Do you really need a POST body? Or would GET parameters (`new EventSource("get_message.php?largest_id=30")`) be enough? – Bergi May 23 '14 at 12:06
  • @Bergi I think GET parameters have an upper char length? I need POST without the char ceiling – blazonix May 23 '14 at 12:12
  • Well, it depends on what your webserver is capable of and some browser quirks. But what's your use case? Are you uploading a file to the location of a stream? – Bergi May 23 '14 at 12:26
  • @Bergi It's actually for a chat application - I'm sending the content of the chat to the server as a parameter - I think this is overkill...but I dunno how else to send data over – blazonix May 23 '14 at 12:27
  • For a chat (with bi-directional, asynchronous messages), SSE are the wrong tool. Use web sockets. – Bergi May 23 '14 at 12:33
  • @Bergi I already implemented some source code with SSE and it seems to work - do you mean that SSE is less suited than web sockets? If so, why? – blazonix May 23 '14 at 12:34
  • Well, because you cannot *send* messages - you only can receive events. Or maybe show us your code for the chat? – Bergi May 23 '14 at 12:35
  • Hmm, I haven't programmed with WebSockets before, and to send, I simply used the $.post(), ajax jquery function, so it's fine, even though the interface isn't as unified as WebSockets - will look into that next time though. :) – blazonix May 23 '14 at 12:37

5 Answers5

23

The EventSource API does not support POST method, however that does not mean that you cannot use SSE with POST. You just cannot use the EventSource API.
There are alternative implementations however. One example is sse.js which allows you to specify a payload, and also headers if you need. sse.js should be a drop-in replacement for EventSource, eg:

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

In order to use a POST method, you just need to specify a payload, eg:

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

And, since it is a fully compatible polyfill, you can probably do this:

EventSource = SSE;
var source = new EventSource("get_message.php", {payload: 'Hello World'});
source.onmessage=function(event)
{
    document.getElementById("message-window").innerHTML+=event.data + "<br>";
};
mjs
  • 2,837
  • 4
  • 28
  • 48
  • To start the process, you need to call `source.stream();`. This held me up until I read the docs. Issue at https://github.com/mpetazzoni/sse.js/issues/16 – Rick Hitchcock Aug 04 '23 at 16:29
7

I searched for this problem and found a related solution to share with you.

First, you need to change the backend interface to support POST requests. The web page normally initiates POST requests with parameters. Note that you need to add the request header "Accept": "text/event-stream". The following is a small piece of code. This operation requires you Handles message parsing and 'retry'

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));
    }
z.houbin
  • 216
  • 3
  • 6
  • This approach seems to occasionally batch multiple events in one chunk: `'data: {"test": "105"}\n\ndata: {"test": "106"}\n\n'` which doesn't occur with the `EventSource` option. – ggorlen Jun 08 '23 at 19:20
5

The downside of submitting a POST request to initiate EventSource is reconnection to the event stream, which is part of the specification. Since the browser must be able to reestablish the connection to the same EventSource, identifying the request with POST data would mean posting the same data again on every reconnect attempt. This is the intended use of POST request according to initial RFC 2616 and providing alternate URL or separate mechanism for reconnection would probably overcomplicate the SSE implementation for browser JavaScript and is also a practical design problem when you use POST query to initiate EventSource.

ramtam
  • 1,638
  • 2
  • 12
  • 5
0

@blazonix you must differentiate between sending and receiving when using SSE.

EventSource is meant only for receiving data from server. To send data to server you must use regular AJAX request.

In my library I'm making it possible to reuse the same path for sending and receiving but I'm distinguishing what the caller wants to do based on Accept header:

  • Accept: text/event-stream - it is a browser and wants to initiate event stream connection
  • Accept: any other type - it is a regular non/AJAX call GET or POST

Sample java code: GitHub

MeTTeO
  • 2,088
  • 16
  • 19
-6

That is so simple.

$.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.
});
fiorebat
  • 3,431
  • 2
  • 18
  • 18
  • I thought that this was only for GET requests? What if I wanted to process POST requests? The parameters are very likely to exceed the upper char length, which GET parameters impose, I believe? – blazonix May 23 '14 at 12:13