Как я исправил ошибки запросов Ajax к внешним ресурсам (CSP) внутри Discourse

Если у вас возникли проблемы с AJAX-запросом, и вы предполагаете, что ошибка может быть вызвана директивой Content Security Policy (CSP) strict-origin-when-cross-origin, есть несколько шагов, которые можно предпринять для её устранения (обратите внимание на сообщения в консоли ошибок Chrome DevTools):

  1. Убедитесь, что сервер настроен на включение заголовка Access-Control-Allow-Origin как в ответе на предварительный запрос (preflight), так и в ответе на сам AJAX-запрос. Этот заголовок разрешает доступ к ресурсу из указанного источника.

Ниже приведён пример настройки заголовка Access-Control-Allow-Origin на сервере Node.js с использованием библиотеки cors:

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', '*');
  1. Убедитесь, что сервер настроен на разрешение заголовков, используемых в предварительном запросе и в самом AJAX-запросе. Это можно сделать, включив эти заголовки в значение заголовка Access-Control-Allow-Headers.

Ниже приведён пример настройки заголовка Access-Control-Allow-Headers на сервере Node.js:

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('Запрос получен');
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ likes: 100 }));
    } else {
        res.writeHead(404);
        res.end();
    }
});

server.listen(3000, () => {
    console.log('Сервер запущен на порту 3000');
});

process.on('SIGINT', () => {
    console.log('Остановка сервера');
    server.close();
});

Обратите внимание на два дополнительных разрешённых заголовка, специфичных для Discourse:
discourse-present, discourse-logged-in, discourse-track-view

Надеемся, что эти шаги помогут вам устранить проблему с AJAX-запросом. Если у вас возникнут вопросы, дайте нам знать.

4 лайка