How can I browser to render links in streamed content in Django?
Problem:
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']}\n\n"
if chunk['choices'][0]['finish_reason'] == 'stop': break |
Solution 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.
Suggested blogs:
>Make Xdebug stop at breakpoints in PhpStorm using Docker
>Creating a service in Laravel using app(FQCN)
>Can not run phpstan under docker with memory lack error
>Attempt to read property "data_audit" on array laravel view loop foreach
>How to use start and limit on DataTables in Laravel for mobile API?
>How you can Show or hide elements in React?
>Login to Laravel API- Laravel
>Implement nested serializers in the Django rest framework
>Define blade component property in server - Laravel