设置跨源资源共享(CORS)

:notebook_with_decorative_cover: 这是一个#how-to::tag 指南,将指导您完成在 Discourse 中设置跨域资源共享 (CORS) 的过程。

CORS 是一种机制,允许网页上的许多资源(例如字体、JavaScript 等)从资源来源域之外的另一个域请求。

以下是如何在您的 Discourse 站点上设置 CORS:

先决条件

在开始之前,必须将 DISCOURSE_ENABLE_CORS 环境变量设置为 true 以启用 CORS。

有关此方面的帮助,请参阅如何设置环境变量

:sparkles: 如果您使用的是 Discourse 托管站点,此步骤已完成,您无需采取任何额外措施进行配置。

访问站点设置

转到您的 Discourse 管理面板。然后导航到“设置”选项卡。

查找 CORS 设置

在“设置”选项卡中,使用搜索栏并键入 cors origin。您应该会看到以下与 CORS 相关的设置:

此设置允许您指定允许向您的 Discourse 实例发出跨域请求的域。

您应该在此处输入确切的域,用空格分隔。避免使用通配符 (*),因为这可能会带来安全风险。

在此处添加多个域时,每个 URL 都应分开。例如:

保存更改

做出必要的更改后,请不要忘记单击页面底部的“保存更改”按钮。

重要提示

不正确地实现 CORS(跨域资源共享)可能会带来潜在的安全风险。以下是在您的站点上启用 CORS 时需要牢记的一些事项:

  • 指定确切的域:在 CORS 配置中使用通配符 (*) 允许任何域与您的服务器交互,这是一个重大的安全风险。建议指定确切的域。
  • 最小化暴露的数据:CORS 应设置为仅公开您信任的外部域的必要数据。不建议允许您不控制的站点进行 CORS 访问。
  • 使用 HTTPS:如果可能,避免在 CORS 配置中允许非 HTTPS 站点,因为这可能会以未加密的格式暴露数据。
2 个赞

如果使用了 Google Ads,也许最好不要更改此设置 :wink:

CORS(和 CSP)有点麻烦,因为网站通常必须允许几乎所有内容,那样它就几乎没用了。

2 个赞

我在站点的 app.yml 文件的 env 部分添加了 DISCOURSE_ENABLE_CORS: "true"
然后我重建了应用程序。
然后我进入 cors_origins 部分,添加了我试图进行交互的站点的完整 URL,但它仍然不起作用。
我创建了一个页面,在主站点离线时提供信息。
我将这段 JavaScript 放在页面中,用于检查主站点,并在主站点恢复联机时重定向到它,但它似乎不起作用。
代码如下:

    <script>
        function checkSiteStatus() {
            fetch('https://discourse.technospider.com', {
                method: 'HEAD',
                mode: 'cors', // 使用 CORS 获取状态码
                cache: 'no-store' // 避免缓存
            })
            .then(response => {
                console.log('Site check: Status', response.status);
                if (response.ok) { // 200-299 状态码
                    console.log('Site is up, redirecting to Discourse');
                    window.location.replace('https://discourse.technospider.com');
                } else {
                    console.log('Site is still down (status: ' + response.status + '), retrying in 20 seconds');
                    setTimeout(checkSiteStatus, 20000);
                }
            })
            .catch(error => {
                console.log('Site check: Error (likely down or CORS issue):', error.message);
                setTimeout(checkSiteStatus, 20000);
            });
        }
            
        // 立即开始检查
        checkSiteStatus();
    </script>

这是控制台错误:

[Error] Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200
[Error] Fetch API cannot load https://discourse.technospider.com/ due to access control checks.
[Error] Failed to load resource: Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200 (discourse.technospider.com, line 0)
[Log] Site check: Error (likely down or CORS issue): – "Load failed" (berightback, line 78)

如果有人有什么见解,我很想知道。Grok 和我都束手无策。

尝试去掉双引号,否则它可能被解释为字符串而不是布尔值。

正在等待重建完成进行测试。如果是这种情况,那么有人需要修复此页面:

因为它显示将 true 放在双引号内。

重建完成,没有变化。 :frowning:

嗯,这确实很奇怪……那里的其他环境变量值为 true,且没有引号。

如果想在帖子中使用 JavaScript,这是否比 CSP 更好?

目前,我依赖主题组件或 CSP 来运行 js,

此致
Olle

这里它进入了一个环境变量,它只能是字符串。没关系。

但总的来说,这是一件需要牢记的事情,因为对于看起来无害的值,您可能会得到意想不到的结果:

pry(main)> YAML.load('on: yes').to_s
=> "{true=>true}"
1 个赞