“嵌入错误”评论

TL;DR: 无论我在嵌入设置中允许哪些主机,Discourse 都会显示“嵌入错误”。

我在 foo.com 上发布了一个网站,该网站嵌入了来自 forum.foo.com 的 Discourse 论坛评论,目前运行正常。例如,访问 https://foo.com/blog/2019-11-22/foo-0.9.6-released 时,嵌入的评论显示正常。在这种情况下,页面源代码中的嵌入脚本代码如下:

<div id='discourse-comments'></div>
<script type="text/javascript">
  DiscourseEmbed = { discourseUrl: 'https://forum.foo.com/', discourseEmbedUrl: 'https://foo.com/blog/2019-11-22/foo-0.9.6-released' };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>

我还在本地机器上运行了一个开发版本的网站(localhost),但在嵌入方面遇到了问题——它一直显示“嵌入错误”,而不是在论坛生成并返回的 HTML 中显示评论。也就是说,在嵌入区域的右上角,我看到了论坛的标志和指向它的链接,但评论列表并未出现,取而代之的是该错误消息。

例如,访问 http://localhost:1313/blog/2019-11-22-foo-0.9.6-released/(这是生产站点的等效页面)时,页面源代码中的嵌入脚本代码如下:

<div id='discourse-comments'></div>
<script type="text/javascript">
  DiscourseEmbed = { discourseUrl: 'https://forum.foo.com/', discourseEmbedUrl: 'http://localhost:1313/blog/2019-11-22-foo-0.9.6-released/' };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>

我尝试过在 discourseEmbedUrl 设置中保留或不保留末尾的斜杠 /,但没有任何区别。

我无法直接访问运行论坛的服务器,但我已进入论坛的管理面板,并尝试在嵌入设置中添加多个允许的主机。当前针对正常工作的生产站点的设置如下:

“允许的主机”、“类名”、“路径白名单”、“发布到分类”

foo.com, <空>, /blog/.*, blog

为了让本地开发版本的 localhost 站点也能正常工作,我添加了以下内容:

“允许的主机”、“类名”、“路径白名单”、“发布到分类”

localhost, <空>, /blog/.*, blog
localhost:1313, <空>, /blog/.*, blog
<论坛服务器看到的我的外部/公共 IP 地址>, <空>, /blog/.*, blog
<论坛服务器看到的我的外部/公共 IP 地址>:1313, <空>, /blog/.*, blog

但这些设置均无效,我仍然收到相同的“嵌入错误”消息。

我不太想深入源代码进行调试,更希望了解 Discourse 在决定生成该错误消息时究竟检查了哪些内容。有人能告诉我这一点以及如何解决吗?这应该相当直接,但 Discourse 在这里表现得像个黑盒。

我已经阅读了 Embed Discourse comments on another website via Javascript 的全部内容,但其中并未提供更多有用的信息。

你可能想使用 topicID,具体可参考 Embed Discourse comments on another website via Javascript

如果“localhost”因各种原因被禁止,这并不令人意外。这将指示你的论坛服务器在自身上嵌入内容。:dizzy_face:

如果你使用的是 Hugo,可以条件性地加载评论模板,或在模板中显式传递 baseURL,这样即使在开发期间,你加载的也是 discourseEmbedUrl: 'https://foo.com/blog/2019-11-22/foo-0.9.6-released'

@maiki 非常感谢您抽出时间回复。

按照指南所述使用 topicId 并不能解决问题或改变任何症状。请求的 URL 当然会变为 https://forum.foo.com/embed/comments?topic_id=2279,但返回的错误信息完全相同。

我还尝试将 discourseEmbedUrl 更改为 https://foo.com/blog/2019-11-22/foo-0.9.6-released,但遗憾的是,这也未能改善任何情况。

即使这是有意为之,也需要在文档中说明。例如,来自 localhost 站点的请求是否被阻止?尽管它已明确列在允许的主机列表中?Discourse 是检查 HTTP 请求中的 referrer 字段,还是使用其他什么机制来触发此错误?这一点确实需要澄清,因为到目前为止,我尚未找到任何能解释为何无法工作的原因 :slight_smile:

错误信息是什么?开发控制台里有什么内容吗?

localhost 不是一个有效的域名,它是一个主机名。

我不确定是否需要在嵌入指南中解释这一点,但至少我们有了这个主题作为参考!:slight_smile:

不,本地主机客户端/浏览器的开发控制台中没有任何错误。论坛服务器成功返回了 HTML,我在开发工具中可以清楚地看到它。

正常工作时的样子应该是这样(部分文本已打码):

而实际显示的样子是这样的(部分文本已打码):

所以,问题仅仅是论坛服务器返回了 400 状态码和“嵌入错误”,而不是正确的内容。

没错,但正如你所建议的,也许 Discourse 确实阻止了来自 localhost 引用源的这类请求。我知道“localhost”不是域名,而是主机名。这与论坛嵌入设置中配置的“允许的主机”仅仅是主机这一事实是一致的。

我非常清楚 localhost 是什么,这不是问题所在。

解释什么是 localhost?不,这没必要。当我提到我们需要得出结论,弄清楚为什么它对我来说无法工作,并且必须将其记录下来时,我指的是在一般情况下,为什么这种情况不被预期能正常工作(如果确实如此的话)。再次强调,就目前情况而言,没有任何迹象表明这是预期行为。

您的 Discourse 站点是否设置为“需要登录”?

“登录”部分中名为“需要登录”的设置未勾选,因此不是。

边想边说:本地开发站点发出的请求与生产站点发出的请求之间,差异其实不大。主要区别应该只是 HTTP Referer 以及 HTTP 请求的来源。除此之外,两个站点我使用的是同一个浏览器。

你可以通过尝试将其嵌入到另一个正在运行的域名(也许是你拥有的某个子域名)上来测试这是否是主机问题。

我自言自语:如果我告诉 Discourse 接受 “localhost”,它会在 localhost 查找,也就是 Discourse 服务器。

祝你好运!我也不清楚具体是怎么回事。:slight_smile:

1 个赞

我理解你的逻辑。这时就很有意思了:它究竟在检查什么来决定访问权限,以及是否应该抛出这个错误信息。

相关的一点是,当 Discourse 回复嵌入式请求时,它返回的 HTTP 状态码是 400,这仅表示“错误请求”。如果问题出在非允许的主机或类似情况,我预期状态码应为 401(“未授权”)或类似代码,但事实并非如此。这表明问题与授权或允许的主机无关。但也可能是后端代码未能正确返回合适的 HTTP 状态码。

肯定有人知道是否应该允许在本地开发网站中嵌入来自域名 forum.foo.com 的评论吧?我没看到任何说明(通过允许主机)表示这不可行,但既然无法工作,情况就相当不明确。

看起来背后还有更大的问题。
X-Frame-Options 头部被设置为 ALLOWALL。
但 ALLOWALL 并不是一个有效选项,请参阅 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options。
当我尝试嵌入评论时,会出现以下错误:加载时发现了无效的 X-Frame-Options 头部:'ALLOWALL' 不是有效的指令
只有在使用 topicId 时,评论才能正常加载。但我认为这是因为仅嵌入评论时并不需要完整权限。

感谢您报告该问题。您是在哪个浏览器上遇到此错误?该浏览器是否为最新版本?

这是在 Firefox 上,而且已是最新版本。我检查了 Chrome,它没有报错,但就是无法工作。

1 个赞

如果有人感兴趣,我之前详细描述了我遇到的这个问题实例。不知何故,当我们最终发布网站时,评论嵌入功能运行正常。

也就是说,我之前描述的问题和症状发生在我在自己的系统(如 localhost 或类似环境)上运行嵌入来自 forum.domain.com 评论的网站时。但当我将网站发布到 domain.com 后,它立即就能正常工作了。

正如我之前所说,我在论坛设置中找不到任何禁止从 domain.com 以外的来源访问或嵌入评论的选项,因此在我看来,这为什么无法工作仍然是一个谜。Discourse 代码中肯定有某种机制阻止了它,但具体是什么,我不得而知。

我一直在尝试复现这个问题,但到目前为止尚未成功。使用默认的嵌入脚本时,在最新的 Chrome 和 Firefox 浏览器(运行于 Ubuntu 系统)上,评论都能正常显示,没有任何错误。

另外,请检查您是否已在您网站的“管理 / 自定义 / 嵌入”部分创建了主机记录。我提到这一点是因为我在测试时遇到了错误,原因是我没有填写“创建话题的用户名”设置并保存嵌入设置。

1 个赞

我遇到了类似的问题,我认为,通过在 Admin > Customize > Embedding 中将 Allowed Hosts 从 example.com 更改为 www.example.com 来解决了。我的论坛安装在 subdomain.example.com,这可能就是导致问题的原因。

总之,我不确定这是否会对你有帮助,但希望它能!