skip to Main Content

I am using EventSource to get streamed text content in the browser. The problem is that when I want a link to appear even though I have the correct text, the link doesn’t render.

This is the text that is outputted (correctly)

Here are a few options for single burner camping stoves that you might find suitable:1. The <a href='https://www.bcf.com.au/p/companion-lpg-portable-single-burner-gas-stove/292578.html?cgid=BCF08188'>Companion LPG Portable Single Burner Gas Stove</a> is a great option. It's portable and uses LPG, which is a common fuel type for camping stoves. This makes it a practical choice for camping trips.2. Another good choice is the <a href='https://www.tentworld.com.au/buy-sale/companion-1-burner-wok-cooker-stove'>Companion 1 Burner Wok Cooker Stove</a>. This stove is also portable and has a wok cooker, which adds versatility to your cooking options.For more options, you can check out the range of <a href='https://www.anacondastores.com/camping-hiking/camp-cooking/camping-stoves?q=:relevance:brand:coleman:dealType:OnSale:dealType:CLUB%20PRICE'>Camping Stoves</a> at Anaconda stores. They offer a variety of brands and styles, so you might find other single burner stoves that suit your needs.

And here is the html/js:

<div id="response-display"></div>
<script>
    const responseDisplay = document.getElementById('response-display');
    const eventSource = new EventSource('http://127.0.0.1:8000/do-chat');

    eventSource.onmessage = function(event) {
        console.log('We have a message');
        console.log(event.data);

        // Append received data to the div
        // responseDisplay.textContent += event.data + "n";
        responseDisplay.innerHTML += event.data;
    };

    eventSource.onerror = function(error) {
        console.error('EventSource failed:', error);
        eventSource.close();
    };

</script>

This is the python/django code:

def get_gpt4_streaming_response(self, prompt):
    model_engine = self.MODEL_NAME  
    messages = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model_engine,
        messages=messages,
        temperature=0.5,
        max_tokens=1000,  # You can set this to be as long or short as you'd like
        stream=True
    )

    for chunk in response:
        print(chunk)
        yield f"data: {chunk['choices'][0]['delta']['content']}nn"

        if chunk['choices'][0]['finish_reason'] == 'stop':
            break

2

Answers


  1. When you set the innerHTML of an element, it treats the content as plain text by default, not as HTML. Therefore, the HTML tags within the received data are displayed as text, and the links are not rendered as actual links.

    To render the links correctly, you should use the insertAdjacentHTML method instead of directly setting the innerHTML. Can you check if this works for you?

    const responseDisplay = document.getElementById('response-display');
    const eventSource = new EventSource('http://127.0.0.1:8000/do-chat');
    
    eventSource.onmessage = function(event) {
        console.log('We have a message');
        console.log(event.data);
    
        // Append received data as HTML
        responseDisplay.insertAdjacentHTML('beforeend', event.data);
    };
    
    eventSource.onerror = function(error) {
        console.error('EventSource failed:', error);
        eventSource.close();
    };
    

    EDIT 1:

    Sanitize HTML: Use a library like DOMPurify to sanitize and clean the received HTML to remove any potentially malicious or harmful content.
    DOMPurify is designed to sanitize untrusted HTML and make it safe for rendering in a browser.

    First, include DOMPurify in your HTML:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.2.7/purify.min.js"></script>
    

    Then, modify your JavaScript code to sanitize and render the HTML:

    const responseDisplay = document.getElementById('response-display');
    const eventSource = new EventSource('http://127.0.0.1:8000/do-chat');
    
    eventSource.onmessage = function(event) {
        console.log('We have a message');
        console.log(event.data);
    
        // Sanitize and render the received HTML
        const sanitizedHTML = DOMPurify.sanitize(event.data);
        responseDisplay.insertAdjacentHTML('beforeend', sanitizedHTML);
    };
    
    eventSource.onerror = function(error) {
        console.error('EventSource failed:', error);
        eventSource.close();
    };
    

    This approach ensures that the HTML content is sanitized to remove any potentially harmful elements or scripts before rendering it in the browser.

    Also, check if you can implement Content Security Policy (CSP). It allows you to define which sources of content are allowed to be executed on your page, which can help mitigate the risk of XSS attacks.

    Login or Signup to reply.
  2. Try this modification:

    const responseDisplay = document.getElementById('response-display');
    const eventSource = new EventSource('http://127.0.0.1:8000/do-chat');
    let htmlBuffer = "";
    
    eventSource.onmessage = function(event) {
        console.log('We have a message');
        console.log(event.data);
        htmlBuffer += event.data;
        // Append received data as HTML
        responseDisplay.innerHTML = htmlBuffer;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search