gpt4 book ai didi

JavaScript EventSource 在 Apache 基本身份验证后不会打开连接

转载 作者:行者123 更新时间:2023-11-27 22:38:37 26 4
gpt4 key购买 nike

我不负责 Apache 配置,所以我不确定我可以在有用的配置文本方面提供什么,但我相当确定我已经将问题范围缩小到登录。 EventSource 在无需任何登录的情况下在 XAMPP 本地运行以及在生产服务器上进行身份验证后刷新页面后都可以完美运行,但服务器上的首次加载不会打开连接。以前有人见过这个问题吗?经过过去几天的搜索,我在互联网上找不到任何与此相关的内容。

编辑:一些代码

一些服务器端代码(大部分不相关):

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

$client_stream = new RedisStream();
$client_stream->poll(1); //The loop, with sleep time as a parameter

JavaScript:

var xhttpViewSet;
var xhttpSearch;
var view = 'tile';
var search = '';

var seed_url = '/core/seed_view.php';
var stream_url = '/core/stream.php';

var default_class = 'panel-default';
var success_class = 'panel-success';
var warning_class = 'panel-warning';
var danger_class = 'panel-danger';

function UpdateClient(c_name, c_obj) {
if ((c_element = document.getElementById(c_name)) !== null) {
c_element.classList.remove('text-muted');

c_element.classList.remove(default_class);
c_element.classList.remove(success_class);
c_element.classList.remove(warning_class);
c_element.classList.remove(danger_class);

switch (c_obj['status']) {
case 0:
c_obj['status'] = 'OK';
c_element.classList.add(success_class)
break;
case 1:
c_obj['status'] = 'Warning';
c_element.classList.add(warning_class)
break;
case 2:
c_obj['status'] = 'Critical';
c_element.classList.add(danger_class)
break;
default:
c_obj['status'] = 'Unknown';
c_element.classList.add(danger_class)
break;
}

for (i in c_obj) {
var var_nodes = c_element.getElementsByClassName(i);
if (var_nodes.length > 0) {
for (var j = var_nodes.length - 1; j >= 0; j--) {
var_nodes[j].innerHTML = c_obj[i];
}
}
}
}
}

function SetView() {
var view_url = seed_url + '?search=' + search + '&view=' + view;

xhttpViewSet.open('GET', view_url, true);
xhttpViewSet.send();
}

var main = function() {
container = document.getElementById('content');

if (new XMLHttpRequest()) {
xhttpViewSet = new XMLHttpRequest();
xhttpSearch = new XMLHttpRequest();
} else {
xhttpViewSet = new ActiveXObject('Microsoft.XMLHTTP');
xhttpSearch = new ActiveXObject('Microsoft.XMLHTTP');
}

var stream = new EventSource(stream_url);
stream.onopen = function() {
console.log('Connection opened.'); //This doesn't fire
}

stream.onmessage = function(e) {
var c_obj = JSON.parse(e.data);
UpdateClient(c_obj.name, c_obj.value);
};

xhttpViewSet.onreadystatechange = function() {
if (xhttpViewSet.readyState == 4) {
var resp = xhttpViewSet.responseText;
if (xhttpViewSet.status == 200 && resp.length > 0) {
container.innerHTML = resp;
if (view == 'list') {
$('#computer-table').DataTable({
"lengthMenu": [[25, 50, 100], [25, 50, 100]]
});
}
} else {
container.innerHTML = '<error>No computers matched your search or an error occured.</error>';
}
}
}
SetView(); //This successfully does all but make the EventSource connection, and only fails to do that on first load

document.getElementById('list-view').addEventListener('click', function() {
view = 'list';
SetView();
});

document.getElementById('tile-view').addEventListener('click', function() {
view = 'tile';
SetView();
});

document.getElementById('search').addEventListener('keyup', function() {
search = this.value.toUpperCase();
SetView();
});

document.getElementById('clear-search').addEventListener('click', function() {
document.getElementById('search').value = '';
search = '';
SetView();
});
};

window.onload = main;

最佳答案

如果没有更多信息,很难确定,但根据您到目前为止所说的,我认为它是以下之一:

HEAD/OPTIONS:某些浏览器会在发送 GET 或 POST 之前向服务器脚本发送 HEAD 或 OPTIONS http 调用。发送OPTIONS的目的是询问允许发送哪些 header 。这可能是登录过程的一部分;这可能解释了为什么它在您重新加载时起作用。有关更多详细信息,请参阅《使用 HTML5 SSE 的数据推送应用程序》(免责声明:我的书)第 9 章;基本上,在 SSE 脚本的顶部,您需要检查 $_SERVER["REQUEST_METHOD"] 的值,如果它是 "OPTIONS",则拦截并说出哪些 header 你想要接受。我以前用过这个:

header("Access-Control-Allow-Headers: Last-Event-ID,".
" Origin, X-Requested-With, Content-Type, Accept,".
" Authorization");`

CORS: HTML 页面 URL 和 SSE 页面 URL 必须具有相同的来源。使用 HTML5 SSE 的数据推送应用程序的第 9 章(再次)有详细的解释(特定于 SSE),或者(不太具体)在 Wikipedia 。如果这是问题所在,请考虑将 header("Access-Control-Allow-Origin: *"); 添加到您的 SSE 脚本中。

withCredentials: SSE 构造函数有第二个参数,您可以像这样使用它:var stream = new EventSource(stream_url, { withCredentials: true }); 它表示可以发送身份验证凭据。 (本书的第 9 章再次介绍了更多详细信息 - 对于重复的插入感到抱歉!)还有第二步,在服务器端:在 PHP SSE 脚本的顶部,您需要添加以下内容。

header("Access-Control-Allow-Origin: ".@$_SERVER["HTTP_ORIGIN"]);
header("Access-Control-Allow-Credentials: true");

PHP session 锁定: 这通常会导致相反的问题,即 SSE 脚本已锁定 PHP session ,因此其他 PHP 脚本无法工作。请参阅https://stackoverflow.com/a/30878764/841830如何处理它。 (无论如何,这样做都是个好主意,即使这不是您的问题。)

关于JavaScript EventSource 在 Apache 基本身份验证后不会打开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38921068/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com