我Hono+Ditto
使用安装helm-charts
,如cloud2edge中所述。
这意味着 Hono+Dittominikube
在我的 PC 上运行。我还创建了连接、策略和设备。到目前为止一切正常。
在下一步中,我只是编写了一个简单的“前端”来从 Ditto-HTTP-API 获取事物状态。只要我通过 fetch-API 手动获取事物状态,一切都很好。但是,一旦我尝试使用 SSE(事件源),就会收到以下 CORS 错误:
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'.
从昨天开始,我一直在为这个错误而苦苦挣扎,我在互联网上找到的关于 CORS 错误的答案都没有工作:(。
如何使用 Eventsource 从我的 PC 与 Ditto 通信而不会出现 CORs 错误?
下面是我的简单前端:
<!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>
谢谢!