你好,我在尝试将 JavaScript 嵌入集成到我们的网站时遇到了完全相同的错误。
我已经查看了相关主题并进行了谷歌搜索,但仍不确定该如何解决此问题。谢谢!
[编辑] 由于我不想让此错误消息一直显示,因此我仅在此一篇旧帖子中启用了它。
嵌入设置:
尝试过的设置:
host: royaleapi.com
path allowed: /blog/.*
host: royaleapi.com
path allowed:
我还为以下域名启用了 CORS 来源:
https://royaleapi.com
https://cdn.royaleapi.com
此外,我还在 app.yml 的 ENV 中添加了 DISCOURSE_ENABLE_CORS: true,所以我现在有点卡住了……
simon
2020 年11 月 6 日 20:30
2
你确定 ?discuss=1 查询参数不是导致问题的原因吗?
你的博客分类是否设置了任何安全权限,还是已设置为允许“所有人”组进行“创建/回复/查看”?
你的网站使用的是哪个版本的 Discourse?
另外,在 Failed to execute postMessage on DOMWindow 文本之后,你看到的具体错误信息是什么?我预计它应该是类似 The target origin provided (<target_url>) does not match the recipient window's origin (<origin_url>) 的内容。
我确定这与 ?discuss=1 参数无关。没有它我也遇到过同样的问题——只是因为这是一个在线站点,我不想向我们的用户显示巨大的错误块。但既然你问了,我已经编辑了站点,改为仅在我们的一篇非常旧的帖子中启用 JavaScript 嵌入,那里应该不会有访客。所以没有查询字符串。(我已更新我的首条帖子以反映这一点)
https://royaleapi.com/blog/season3
https://royaleapi.com/blog/season3
Discourse 版本
2.6.0.beta5
操作系统版本
Ubuntu 20.04.1 LTS
完整错误信息
VM469 embed-application-9cef8308c816fc1d83137e63d6c556c6cc2b68fe2b6e5ce16cca6766ba2c0ae4.js:1 在 ‘DOMWindow’ 上执行 ‘postMessage’ 失败:提供的目标源(‘https://discuss.royaleapi.com ’)与接收窗口的源(‘https://royaleapi.com ’)不匹配。
博客分类
这是一个公开分类——对所有人开放。我实际上已经将其设置为没有帖子。我刚刚创建了一篇新帖子,以查看该分类中是否必须包含单个项目。
截图:桌面端
截图:移动端
不确定这是否相关,但我在日志中看到了一些错误,不过我不确定具体是什么:
[Fri 06 Nov 2020 04:47:14 PM UTC] 域名未更改。
[Fri 06 Nov 2020 04:47:14 PM UTC] 跳过,下次续期时间为:Mon 04 Jan 2021 08:07:59 AM UTC
[Fri 06 Nov 2020 04:47:14 PM UTC] 添加 '--force' 以强制续期。
[Fri 06 Nov 2020 04:47:14 PM UTC] 正在将密钥安装到:/shared/ssl/discuss.royaleapi.com_ecc.key
[Fri 06 Nov 2020 04:47:14 PM UTC] 正在将完整证书链安装到:/shared/ssl/discuss.royaleapi.com_ecc.cer
[Fri 06 Nov 2020 04:47:14 PM UTC] 运行重载命令:sv reload nginx
警告:nginx:无法打开 supervise/ok:文件不存在
[Fri 06 Nov 2020 04:47:14 PM UTC] 重载错误:
已启动 runsvdir,PID 为 663
ok: run: redis: (pid 677) 0s
chgrp:无效的组:'syslog'
ok: run: postgres: (pid 675) 0s
rsyslogd: imklog:无法打开内核日志 (/proc/kmsg):操作不允许。
rsyslogd: imklog 模块激活失败 [v8.1901.0 请查看 https://www.rsyslog.com/e/2145 ]
supervisor pid: 671 unicorn pid: 702
另外,请告诉我其中是否有任何内容需要脱敏。既然我已经发布了该 URL,我认为这应该无害,因为这些文件路径看起来是该环境的标准配置。
@simon 这是否有可能由您协助解决?这是预期行为,还是将在未来的版本中修复?
我们添加这个论坛主要是为了支持在我们网站页面上进行评论。如果此功能无法使用,我们需要考虑其他解决方案。
谢谢!
simon
2020 年11 月 30 日 23:12
7
这张截图中有一个我之前没注意到的问题:
路径白名单被设置为 /blog/*,而不是 /blog/.*(注意多了一个点号)。
尝试编辑主机条目,将路径白名单更改为 /blog/.*。
如果这不能解决问题,请尝试 /.*。也可以尝试将该设置留空。
是的,我的截图确实显示了该问题,但我后来意识到它很可能使用了正则表达式,因此已经将其改为 /blog/.*。不过,问题仍然存在。
@simon 我已经尝试了以下三种方式:
/blog/.*
/.*
(最后一个是空的),但都不起作用。
我在控制台中看到的错误看起来更像是 CORS 问题:
_embed-application-9cef8308c816fc1d83137e63d6c556c6cc2b68fe2b6e5ce16cca6766ba2c0ae4.js:7
在 'DOMWindow' 上执行 'postMessage' 失败:
提供的目标源 ('https://discuss.royaleapi.com')
与接收窗口的源 ('https://royaleapi.com') 不匹配。
但我不确定该如何修复。为了测试,我已经在应用配置中添加了以下内容:
DISCOURSE_ENABLE_CORS: true
DISCOURSE_CORS_ORIGIN: '*'
基本上将其设置为完全开放,但这仍然不起作用。
simon
2020 年12 月 1 日 01:44
10
在 Discourse 嵌入设置页面中,您是否已设置“创建话题的用户名”选项?如果未设置,您将遇到 Failed to execute 'postMessage' on 'DOMWindow' 错误。
@simon 是的,创建主题的用户名已设置为 system。我也尝试将其设置为我自己的用户名,但出现了相同的错误。
值得注意的是,今天我发现了以下情况:
curl -IXGET https://discuss.royaleapi.com
access-control-allow-origin: *
access-control-allow-headers: Content-Type, Cache-Control, X-Requested-With, X-CSRF-Token, Discourse-Present, User-Api-Key, User-Api-Client-Id, Authorization
access-control-allow-credentials: true
[已截断]
然而:
curl -IXGET https://discuss.royaleapi.com/javascripts/embed.js
HTTP/2 200
server: nginx
date: Tue, 08 Dec 2020 23:52:26 GMT
content-type: application/javascript
content-length: 2404
last-modified: Tue, 01 Dec 2020 01:49:39 GMT
vary: Accept-Encoding
expires: Wed, 09 Dec 2020 23:52:26 GMT
cache-control: max-age=86400
cache-control: public,immutable
accept-ranges: bytes
这是否就是原因?看起来脚本本身并没有 access-control-allow-origin 头,即使域名有。我是否应该尝试使用自己的 nginx 配置,而不是使用 Docker 镜像中内置的配置?
@simon 我已解决此问题。
为了解决另一个问题 https://meta.discourse.org/t/unable-to-generate-preview-for-urls/175758/4,我在网站上启用了 HEAD 请求。现在所有讨论都已显示,我的博客文章也自动生成了相应的主题。
这太棒了——我简直不敢相信,我竟然钻进了判断这是否与 CORS 相关的牛角尖,而实际上问题出在 HEAD 请求上。或许需要在文档中明确说明这一点。
请将此问题标记为已关闭。
simon
2021 年1 月 14 日 00:22
13
非常感谢您跟进此事!
seeminglee:
也许需要在文档的某个地方明确说明这一点。
或许应该将此内容添加到 Embed Discourse comments on another website via Javascript 的“故障排除”部分。我不确定 HEAD 请求被禁用的情况有多普遍,但对于那些禁用了 HEAD 请求的网站来说,排查这个问题相当困难。
Falco
(Falco)
2021 年1 月 14 日 00:30
14
好吧,如果你特意去拦截那些对 GET 请求有响应的 URL 的 HEAD 请求,从而违反了 RFC,那么出现一些故障不是也在情理之中吗?
说实话,我没想到有服务依赖它的存在。如果我知道它是必需的,我就不会“禁用”这个方法了。
另外,澄清一下:我并不是特意要去禁用这个方法。我只是没有编写支持 HEAD 方法的路由。所以我现在所做的,就是添加一个函数,来响应所有发往有效端点的 HEAD 请求。
实际上,@Falco 指出只需运行
curl https://example.com/path/to -I
即可显示该方法是否已实现。这看起来是一个很好的检查方式。
无论如何,非常感谢你们两人的帮助!
Falco
(Falco)
2021 年1 月 14 日 00:55
17
哦,抱歉。我想是像 Rails 这样的框架把我宠坏了,以至于我以为这应该是网站开箱即用的默认行为
好的,请更新故障排除部分,加入以下内容。我遇到了 CORS/帧安全方面的问题,希望按照 @seeminglee 的步骤操作能有所帮助。如何启用 HEAD 请求?
@willywongi 你可能对我的问题有些误解,让我来解释一下具体情况。
我按照步骤操作了,但无法将评论嵌入到网站中。
后来发现,我的 Discourse 应用(安装在另一个域名上)无法“验证”我的博客文章是否存在,因为我的主站没有在这些 URL 上实现 HEAD 方法。
在为这些路径实现 HEAD 请求处理器后,嵌入功能便正常工作了。
要检查你是否遇到和我一样的问题,可以对包含博客文章的 URL(或你希望评论嵌入出现的位置)运行 curl 命令。
例如,如果你的 URL 是 https://example.com/blog/awesome-post,请在终端中运行:
curl https://example.com/blog/awesome-post -I
这将向该 URL 发送一个 HEAD 请求并返回结果。如果状态码不是 200(即响应第一行的数字),例如:
HTTP/2 200
则说明服务器未实现 HEAD 方法(或者在响应时存在问题)。
如果响应状态码确实是 200,那么嵌入问题与 HEAD 请求无关。
哈哈,现在清楚了!谢谢。
我检查了 HEAD 方法,我的网站能正确(200)响应。
我仍在努力嵌入 Discourse 主题,但如果其他任何地方失败,我会另开一个新主题。
emurillo
(Emmanuel Murillo)
2022 年4 月 26 日 15:00
21
遇到这个问题,结果发现是因为我更改了“创建主题的用户名”的调用方式,却忘记在嵌入页面中更新它。我想它试图创建主题却找不到用户名。在嵌入设置页面更新后,错误就消失了。