Cómo solucioné los errores de solicitud Ajax a recursos externos (CSP) en Discourse

Si tienes problemas con una solicitud AJAX y crees que el error podría deberse a la directiva de Política de Seguridad de Contenido (CSP) strict-origin-when-cross-origin, hay algunas cosas que puedes intentar para solucionar el problema (observa esto en la consola de errores de Chrome Devtools):

  1. Asegúrate de que el servidor esté configurado para incluir la cabecera Access-Control-Allow-Origin en la respuesta a la solicitud de pre-vuelo, así como a la solicitud AJAX real. Esta cabecera permite que el recurso sea accedido desde el origen especificado.

Aquí tienes un ejemplo de cómo puedes configurar la cabecera Access-Control-Allow-Origin en un servidor Node.js utilizando la biblioteca cors:

const cors = require('cors');

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

Alternativamente, puedes incluir la cabecera Access-Control-Allow-Origin directamente en tu código del lado del servidor. Por ejemplo, en un servidor Node.js, puedes establecer la cabecera de esta manera:

res.setHeader('Access-Control-Allow-Origin', '*');
  1. Asegúrate de que el servidor esté configurado para permitir las cabeceras que se utilizan en la solicitud de pre-vuelo y en la solicitud AJAX real. Esto se puede hacer incluyendo estas cabeceras en la cabecera Access-Control-Allow-Headers.

Aquí tienes un ejemplo de cómo puedes configurar la cabecera Access-Control-Allow-Headers en un servidor Node.js:

const http = require('http');

const server = http.createServer((req, res) => {
    
    res.setHeader('Access-Control-Allow-Origin', '*'); // Añade esta línea para permitir que el recurso sea accedido desde cualquier origen
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS'); // Añade esta línea para permitir el uso de los métodos HTTP especificados
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, discourse-present, discourse-logged-in, discourse-track-view'); // Añade esta línea para permitir el uso de las cabeceras especificadas

    if (req.url === '/getTopicLikes') {
        console.log('Solicitud recibida');
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ likes: 100 }));
    } else {
        res.writeHead(404);
        res.end();
    }
});

server.listen(3000, () => {
    console.log('Servidor iniciado en el puerto 3000');
});

process.on('SIGINT', () => {
    console.log('Cerrando el servidor');
    server.close();
});

Ten en cuenta las dos cabeceras de permiso adicionales específicas de Discourse:
discourse-present, discourse-logged-in, discourse-track-view

Espero que estos pasos te ayuden a solucionar el problema con tu solicitud AJAX. Avísame si tienes alguna pregunta.

4 Me gusta