I installed Hono+Ditto
using helm-charts
, as it is described in cloud2edge.
That means Hono+Ditto is running inside a minikube
on my PC.
I also created a connection, policy, and a device. So far everything works fine.
In the next step, I just wrote a simple "frond-end" to fetch the thing state from Ditto-HTTP-API. As long as I fetch the thing state manually by the mean of fetch-API everything is fine. But as soon as I try to use the SSE (Eventsource) I get the following CORS error:
index.html:1 Access to resource at 'http://192.168.99.100:32084/api/2/things/de.iot1:dev1' from
origin 'http://localhost:63342' has been blocked by CORS policy: The value of the
'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'
when the request's credentials mode is 'include'.
I am just struggling with this error since yesterday and none of the answers regarding CORS-errors I found on the internet worked :(.
How can I communicate with Ditto from my PC using Eventsource without getting CORs-error?
Below is my simple front-end:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
{
box-sizing: border-box;
}
.container {
display: grid;
}
.row:after {
content: "";
display: table;
clear: both;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<label for="selector">Choose update strategy:
<select name="method" id="selector">
<option value="auto">Autorefresh</option>
<option value="SSE">SSE</option>
</select>
</label>
</div>
<div class="row">
<label for="dev"><h3>Device state:</h3></label>
</div>
<div class="row">
<textarea id="dev" name="dev-data" rows="20" cols="50"></textarea>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>
<script>
const baseUrl = "http://192.168.99.100:32084"; // Ditto IP:PORT
const username = "ditto";
const password = "ditto";
const interval = 1000;
const thingId = "de.iot1:dev1";
const thingUrl = `${baseUrl}/api/2/things/${thingId}`;
let intervalId;
let eventSource = null
function requestData(url) {
var headers;
headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Basic ' + btoa(`${username}:${password}`));
init = {
method: 'GET',
headers: headers,
};
var request = new Request(url);
return fetch(request, init)
.then(function (response) {
if (response.ok) {
return response;
}
throw response;
})
}
function updateDeviceState(data) {
$('#dev').val(JSON.stringify(data, null, 2));
}
function onRefresh() {
requestData(thingUrl)
.then(response => {
for (var pair of response.headers.entries()) {
console.log(pair[0] + ': ' + pair[1]);
}
return response.json()
})
.then(data => { updateDeviceState(data) });
}
function enableAutoRefresh(enabled=true) {
if (enabled) {
intervalId = setInterval(() => { onRefresh() }, interval);
} else {
clearInterval(intervalId);
}
}
function enableEventSource(enabled=true) {
if (enabled) {
eventSource = new EventSource(thingUrl, {withCredentials: true})
eventSource.addEventListener('message', (e) => { console.log(e) })
} else if (eventSource != null) {
eventSource.removeEventListener('message', this.eventListener)
eventSource.close();
eventSource = null;
}
}
function applyUpdateStrategy() {
let val = $('#selector').val();
let autoRefreshEnabled = val.includes('auto');
enableAutoRefresh(autoRefreshEnabled);
enableEventSource(!autoRefreshEnabled);
}
$('#selector').on('change', () => { applyUpdateStrategy() })
applyUpdateStrategy()
</script>
</body>
</html>
Thanks!
Thank you for reaching out. You found a bug which was already fixed the Ditto nginx configuration, however not yet applied to the "packages" project. I created a PR to fix this, so this should be fixed in the next Helm version of the Ditto chart: https://github.com/eclipse/packages/pull/193
This question would have been better placed on GitHub as issue - but you could of course not have known that this was a bug before.