我如何修复Discourse中的Ajax请求到外部资源的错误(CSP)

如果您在使用 AJAX 请求时遇到问题,并认为问题可能源于 strict-origin-when-cross-origin 内容安全策略 (CSP) 指令,您可以尝试以下几种方法来解决此问题(请在 Chrome Devtools 的错误控制台中观察):

  1. 确保服务器已配置为在预检请求和实际 AJAX 请求的响应中都包含 Access-Control-Allow-Origin 标头。此标头允许从指定来源访问资源。

    以下是如何使用 cors 库在 Node.js 服务器中配置 Access-Control-Allow-Origin 标头的示例:

    const cors = require('cors');
    
    app.use(cors({
      origin: 'http://example.com',
      optionsSuccessStatus: 200
    }));
    

    或者,您可以直接在服务器端代码中包含 Access-Control-Allow-Origin 标头。例如,在 Node.js 服务器中,您可以这样设置标头:

    res.setHeader('Access-Control-Allow-Origin', '*');
    
  2. 确保服务器已配置为允许在预检请求和实际 AJAX 请求中使用的标头。这可以通过在 Access-Control-Allow-Headers 标头中包含这些标头来完成。

    以下是如何在 Node.js 服务器中配置 Access-Control-Allow-Headers 标头的示例:

    const http = require('http');
    
    const server = http.createServer((req, res) => {
    
        res.setHeader('Access-Control-Allow-Origin', '*'); // 添加此行以允许从任何来源访问资源
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS'); // 添加此行以允许使用指定的 HTTP 方法
        res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, discourse-present, discourse-logged-in, discourse-track-view'); // 添加此行以允许使用指定的标头
    
        if (req.url === '/getTopicLikes') {
            console.log('Request received');
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ likes: 100 }));
        } else {
            res.writeHead(404);
            res.end();
        }
    });
    
    server.listen(3000, () => {
        console.log('Server started on port 3000');
    });
    
    process.on('SIGINT', () => {
        console.log('Shutting down the server');
        server.close();
    });
    
    

    请注意,Discourse 特有的两个附加允许标头:
    discourse-present, discourse-logged-in, discourse-track-view

    希望这些步骤能帮助您解决 AJAX 请求的问题。如果您有任何疑问,请告诉我。

4 个赞