同上 HTTP API 服务器发送事件 CORS 错误

Ditto HTTP API server sent events CORS error

我使用 helm-charts 安装了 Hono+Ditto,如 cloud2edge 中所述。

这意味着 Hono+Ditto 在我的 PC 上 运行 位于 minikube 中。 我还创建了连接、策略和设备。到目前为止一切正常。

在下一步中,我只是编写了一个简单的“前端”来从 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'.

我从昨天开始就一直在为这个错误而苦苦挣扎,none 我在互联网上找到的关于 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>

谢谢!

感谢您与我们联系。 您发现了一个错误,该错误已经修复了 Ditto nginx 配置,但尚未应用于“packages”项目。 我创建了一个 PR 来解决这个问题,所以这应该在 Ditto 图表的下一个 Helm 版本中得到修复: https://github.com/eclipse/packages/pull/193

这个问题最好放在 GitHub 作为问题 - 但你当然可能不知道这是一个错误。