我得到了一个服务器软件,其行为(据我所知)如下:
它接受一个正文包含数字的 HTTP POST 请求。然后,通过使用此数字进行某种形式的计算,它会不断在字符串中生成新数字(每次计算需要几秒钟)。生成数字后,它会立即使用 Server Sent Events 发回该数字。而发出 POST 请求的客户端必须等待并收集数字。
我的任务是写一个客户端来测试这个行为。我对服务器发送的事件和 Javascript 都不太了解,但我编写了以下代码并将其保存在 index.html 中:
<!doctype html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Server Sent Event</title>
</head>
<body>
<div class="event-data"></div>
</body>
<script src=https://code.jquery.com/jquery-1.11.1.js></script>
<script>
let xhr = new XMLHttpRequest();xhr.open("POST", http://localhost:8080/generate?connector=myconnector?env=default);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log(xhr.status);
console.log(xhr.responseText);
}};
let data = "{\"Value\":\"43\"}";
xhr.send(data); // EventSource object of javascript listens the streaming events from our go server and prints the message.
var stream = new EventSource("/stream");
stream.addEventListener("message", function(e){
$('.event-data').append(e.data + "</br>")});
</script>
</html>
所以基本上我首先发出 POST 请求,然后打开流以响应发送的服务器端事件。
当我运行我的服务器软件,然后使用 chrome 打开这个文件时,出现以下错误:
Access to resource at 'file:///stream' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted.
/stream:1 Failed to load resource: net::ERR_FAILED
index.html:1 Access to XMLHttpRequest at 'http://localhost:8080/generate?connector=myconnector?env=default' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
index.html:16 0
index.html:17
localhost:8080/generate?connector=myconnector?env=default:1 Failed to load resource: net::ERR_FAILED
所以问题是软件的 CORS 限制阻止了 POST 请求。我该如何解决这个问题?还是我完全误解了如何使用服务器发送的事件?任何帮助将不胜感激。
您看到的错误消息表明浏览器正在阻止您的请求,因为它们违反了同源策略或 CORS 限制。 CORS 是一种在浏览器中实现的安全机制,用于防止跨站点脚本攻击,它要求服务器响应某些标头,指示允许哪些来源访问其资源。
要解决此问题,您可以修改服务器软件以在对预检请求的响应中添加所需的 CORS 标头。在 POST 请求的情况下,浏览器向服务器发送预检请求(OPTIONS 请求)以请求发出实际请求的许可。服务器应使用适当的标头响应此预检请求,包括 Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers 和 Access-Control-Max-Age。
或者,如果您无权修改服务器软件,您可以使用 CORS 代理代表您发出请求。 CORS 代理是一个服务器,它将必要的标头添加到它从目标服务器接收的响应中,并将修改后的响应转发回您的客户端。您可以在线找到几个免费的 CORS 代理服务,您可以使用它们来绕过 CORS 限制。
关于您对服务器发送事件的理解,您的代码似乎是正确的。您正在向服务器发出 POST 请求以开始计算,然后打开一个 EventSource 对象来侦听服务器发送的事件。当服务器生成新数字时,它会将它们作为服务器发送的事件发送回客户端,并且您的代码将它们附加到 HTML 文档中。