Para webs y blogs

Un quiz para tu web

Elige un set de preguntas, ajusta colores y textos y copia el código en tu página. En cada visita aparecen 9 preguntas gratuitas distintas y con cada respuesta se llena el mosaico.

Contenido
Aspecto
Textos

Vista previa

Código para insertar

Pega el código en el lugar de tu página donde debe aparecer el quiz.

Bueno saber

Opcional: inserción a través de tu propio dominio

Si no quieres solicitudes a servidores de terceros, tu servidor web entrega el quiz: reenvía una ruta como /qwissit/ a Qwissit. El navegador de tus visitantes solo habla con tu dominio y Qwissit solo ve la dirección de tu servidor. La inserción directa de arriba sigue siendo la opción sencilla por defecto.

1. Configura tu servidor web: reenvía /qwissit/ a https://www.qwissit.com/widget/v1/, sin cookies, dirección IP ni otros datos de tus visitantes.

nginx
location ^~ /qwissit/ {
    proxy_pass https://www.qwissit.com/widget/v1/;
    proxy_set_header Host www.qwissit.com;
    proxy_ssl_server_name on;
    proxy_set_header X-Forwarded-For "";
    proxy_set_header X-Real-IP "";
    proxy_set_header Cookie "";
    proxy_set_header Referer "";
    proxy_set_header User-Agent "qwissit-proxy";
    proxy_hide_header Set-Cookie;
}
Apache (mod_proxy, mod_ssl, mod_headers)
SSLProxyEngine On
<Location "/qwissit/">
    ProxyPass "https://www.qwissit.com/widget/v1/"
    ProxyAddHeaders Off
    RequestHeader unset Cookie
    RequestHeader unset Referer
    RequestHeader set User-Agent "qwissit-proxy"
    Header unset Set-Cookie
</Location>
Caddy
handle_path /qwissit/* {
    rewrite * /widget/v1{path}?{query}
    reverse_proxy https://www.qwissit.com {
        header_up Host {upstream_hostport}
        header_up -X-Forwarded-For
        header_up -Cookie
        header_up -Referer
        header_up User-Agent qwissit-proxy
        header_down -Set-Cookie
    }
}
PHP (Shared Hosting)

¿Sin acceso a la configuración del servidor (hosting compartido)? Descarga el archivo PHP, guárdalo como qwissit-proxy.php en tu carpeta web y usa /qwissit-proxy.php/qwissit-widget.js como dirección del script. Solo reenvía los archivos del widget.

Descargar qwissit-proxy.php

2. Sustituye la dirección del script en el código de arriba:

<script src="/qwissit/qwissit-widget.js" async></script>

3. Prueba: la llamada con tu dominio debe devolver 200 y content-type: text/javascript. Un 404 apunta a un punto de «Si no funciona»; una página HTML indica que tu CMS se ha quedado con la solicitud.

curl -I https://example.org/qwissit/qwissit-widget.js

Después, en el navegador con las herramientas de desarrollo (F12), pestaña «Red»: no debe aparecer ninguna solicitud a www.qwissit.com.

Si no funciona
  • nginx devuelve 404: las reglas para archivos estáticos como location ~* \.(js|css)$ tienen prioridad sobre las reglas de prefijo simples, y nginx busca qwissit-widget.js en tu servidor. Por eso el fragmento dice location ^~ /qwissit/: el ^~ garantiza que esta ruta siempre se reenvíe.
  • Los cambios solo surten efecto tras recargar: nginx -t && nginx -s reload; en Apache, apachectl configtest && systemctl reload apache2. En Docker, con un archivo de configuración montado por separado, el contenedor sigue viendo la versión antigua después de sustituir el archivo (rsync, cp); entonces solo ayuda reiniciar el contenedor (docker compose restart <servicio>).
  • Apache: los módulos proxy, proxy_http, ssl y headers deben estar activos (a2enmod proxy proxy_http ssl headers). Las reglas van en la configuración del servidor o del VirtualHost, no en el .htaccess. Si solo puedes usar .htaccess, usa el archivo PHP.
  • Archivo PHP: debe estar de verdad en la carpeta web (en TYPO3, en public/); si no, el CMS se queda con la solicitud. El servidor debe pasar a PHP la ruta que sigue al archivo (PATH_INFO): en Apache AcceptPathInfo On (por defecto en muchos hostings), en nginx en la regla de PHP así:
    location ~ \.php(/|$) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        # … your usual fastcgi_pass / include fastcgi_params
    }

Opcional: comprobar resultados a prueba de manipulación

¿Quieres registrar en tu web que alguien ha superado el quiz, por ejemplo para marcar una lección o dar puntos? Entonces deja que Qwissit confirme el resultado. Así nadie puede falsearlo.

Cómo funciona

  1. Tu página da al quiz un código de un solo uso y lo recuerda.
  2. El visitante resuelve el quiz. Qwissit comprueba cada respuesta; las preguntas falladas vuelven hasta que todas estén bien.
  3. Al final, tu página recibe un justificante que solo Qwissit puede emitir y lo envía a tu servidor.
  4. Tu servidor pregunta a Qwissit si el justificante es auténtico y corresponde a tu código y a tu quiz. Solo entonces guarda el resultado.

Qué tienes que añadir

Dos sitios, ambos en PHP. Tus visitantes deben haber iniciado sesión, porque el resultado tiene que pertenecer a alguien.

A) En la página del quiz: Este bloque sustituye al fragmento normal. Ajusta data-set y data-course a tu quiz; los valores están en el código de arriba.

<?php
session_start();   // your visitors are signed in
$nonce = $_SESSION['quiz_nonce']['http'] ??= rtrim(strtr(base64_encode(random_bytes(16)), '+/', '-_'), '=');
?>
<div id="quiz" data-qwissit-widget data-set="12" data-course="13" data-lang="de"
     data-verify="<?= $nonce ?>"></div>
<script src="https://www.qwissit.com/widget/v1/qwissit-widget.js" async></script>
<script>
document.getElementById('quiz').addEventListener('qwissit:finish', function (e) {
  if (!e.detail.passed || !e.detail.token) return;
  fetch('quiz-complete.php', {
    method: 'POST',
    credentials: 'same-origin',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: 'lesson=http&token=' + encodeURIComponent(e.detail.token)
  }).then(function (r) {
    if (r.ok) { /* done: e.g. show a tick */ }
  });
});
</script>

B) Un archivo nuevo quiz-complete.php en la misma carpeta. Pon en QUIZZES los mismos valores de set y course y guarda el resultado en la línea marcada como convenga a tu web.

<?php
// quiz-complete.php – checks the result with Qwissit and saves it only if everything matches
session_start();
const QUIZZES = ['http' => ['set' => 12, 'course' => 13]];   // same values as data-set / data-course

$lesson = (string)($_POST['lesson'] ?? '');
$token = (string)($_POST['token'] ?? '');
$quiz = QUIZZES[$lesson] ?? null;
$nonce = (string)($_SESSION['quiz_nonce'][$lesson] ?? '');
if (!$quiz || $nonce === '' || $token === '') { http_response_code(400); exit; }

$ch = curl_init('https://www.qwissit.com/widget/v1/verify');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query(['token' => $token]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 4,
]);
$r = json_decode((string)curl_exec($ch), true);
curl_close($ch);

if (!is_array($r)) { http_response_code(503); exit; }   // Qwissit not reachable: save nothing
if (($r['valid'] ?? false) !== true
    || !hash_equals($nonce, (string)($r['nonce'] ?? ''))
    || (int)$r['set'] !== $quiz['set'] || (int)$r['course'] !== $quiz['course']) {
    http_response_code(403); exit;                       // forged, already used, expired or another quiz
}
unset($_SESSION['quiz_nonce'][$lesson]);                 // the code counts only once

// ▶ save the result here, e.g. user + $lesson + date (+ $r['wrong'] = failed attempts)

header('Content-Type: application/json');
echo json_encode(['ok' => true]);

El archivo solo guarda si Qwissit confirma el justificante, este pertenece a tu código de un solo uso y procede del quiz correcto. Después el código queda gastado, así que cada resultado cuenta una sola vez. Si ahora no se puede contactar con Qwissit, no se guarda nada: deja que el visitante lo intente más tarde. El justificante vale una hora.

Conviene saber

Texto para tu política de privacidad

Una propuesta que puedes adaptar a tu sitio. No sustituye el asesoramiento jurídico.

Insertado directamente

A través de tu propio dominio (proxy)

Certificaciones y exámenes

¿Qué examen viene después?

Ya puedes practicar 19 exámenes y 21 están en votación. Mira todas las certificaciones con información oficial, vota o propón tu examen.

Ver todas las certificaciones