From 657fe6b1b77a0386cd2604e3083b46b0fa72a669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Ferdinand?= Date: Wed, 18 Jun 2025 20:03:55 +0200 Subject: [PATCH] test --- .DS_Store | Bin 6148 -> 6148 bytes test/script.js | 272 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 test/script.js diff --git a/.DS_Store b/.DS_Store index f30f425b21e7371309ce274a41a354694bf3f777..ca9a239572f0b5b77d8040c2889eae446174ff27 100644 GIT binary patch delta 266 zcmZoMXfc=|#>B!ku~2NHo+2aP#(>?7iv?Ji82L8yF#TlIXJIH|NM$HyDDlk6Pfp6o zPhwzT5MW?nbO6#@{(}LK#lQenH+c(F2a~b+WIJZZdZ@;nbi?4}{M-VtG6(@TG&kSH z1!^eA=6NT4W-}glL>R_UlAE7`SH2(vx7j>p!9{sF`FZI;0~se4)^29!;O7APbTcE% Xcjn3bB90u43=B*l2W^fJS;Gtf;TS;} delta 64 zcmZoMXfc=|#>B)qu~2NHo+2ar#(>?7jO?3vSbj2Y7UN)I+04$t&jFO*EXeVlc{0C< SBL@QzFfuT(Y>p6F!wdlU6b controller.abort(), 10000); // 10 sekunder timeout + + const response = await fetch(proxyUrl, { + signal: controller.signal + }); + + clearTimeout(timeoutId); // Fjern timeout hvis forespørselen lykkes + if (!response.ok) { + throw new Error(`HTTP feil! status: ${response.status}`); + } + + const text = await response.text(); + + // Sjekk om responsen er tom eller ikke inneholder XML + if (!text || text.trim() === '') { + throw new Error('Mottok tomt dokument fra serveren'); + } + + // Enkel validering for å sjekke om responsen ser ut som XML + if (!text.includes('<') || !text.includes('>')) { + throw new Error('Responsen ser ikke ut til å være gyldig XML'); + } + + return text; + } catch (error) { + // Spesifikk håndtering av timeout + if (error.name === 'AbortError') { + console.warn(`Proxy ${i+1} timeout: Forespørselen tok for lang tid`); + lastError = new Error('Timeout - forespørselen tok for lang tid'); + } else { + console.warn(`Proxy ${i+1} feilet:`, error.message); + lastError = error; + } + // Fortsett til neste proxy + } + } + + // Hvis vi kommer hit, har alle proxyer feilet + throw new Error(`Alle proxyer feilet. Siste feil: ${lastError.message}`); + } + + async function fetchRSSFeed(url, container) { + try { + console.log(`Forsøker å hente RSS fra: ${url}`); + + // Bruk fallback-mekanismen for å hente data + const data = await fetchWithFallbackProxy(url); + + // Sjekk om responsen er tom + if (!data || data.trim() === '') { + throw new Error('Mottok tomt dokument fra serveren'); + } + + console.log(`Mottatt data lengde: ${data.length} tegn`); + // Logg de første 100 tegnene for debugging + console.log(`Første 100 tegn av responsen: ${data.substring(0, 100)}...`); + + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(data, 'text/xml'); + + // Sjekk om parsing var vellykket + const parserError = xmlDoc.querySelector('parsererror'); + if (parserError) { + console.error('XML parsing feilet, detaljer:', parserError.textContent); + console.error('Mottatt XML data:', data.substring(0, 500)); // Logg de første 500 tegnene + throw new Error('XML parsing feilet: ' + parserError.textContent); + } + + // Sjekk om dokumentet har root element + const rootElement = xmlDoc.documentElement; + if (!rootElement || rootElement.nodeName === 'html') { + console.error('Ugyldig XML-dokument mottatt:', data.substring(0, 500)); + throw new Error('Ugyldig XML-dokument: Mangler root element eller feil format'); + } + + // Hent artikler fra XML + const items = xmlDoc.querySelectorAll('item'); + + // Fjern lasteindikatoren + container.innerHTML = ''; + + // Sjekk om vi har artikler + if (items.length === 0) { + container.innerHTML = '
Ingen artikler funnet i RSS-feeden.
'; + return; + } + + // Begrens til 10 artikler + const maxArticles = Math.min(items.length, 10); + + for (let i = 0; i < maxArticles; i++) { + const item = items[i]; + // Håndterer CDATA-seksjoner i tittel og beskrivelse + let title = item.querySelector('title')?.textContent || 'Ingen tittel'; + title = title.replace(/^\s*\s*$/g, ''); // Fjerner CDATA-markører + + const link = item.querySelector('link')?.textContent || '#'; + const pubDate = item.querySelector('pubDate')?.textContent || ''; + + let description = item.querySelector('description')?.textContent || 'Ingen beskrivelse'; + description = description.replace(/^\s*\s*$/g, ''); // Fjerner CDATA-markører + + // Formater dato + const date = pubDate ? new Date(pubDate) : new Date(); + const formattedDate = date.toLocaleString('no-NO', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); + + // Sjekk om artikkelen har et bilde (enclosure) + let imageUrl = ''; + const enclosure = item.querySelector('enclosure'); + if (enclosure && enclosure.getAttribute('url') && enclosure.getAttribute('type')?.startsWith('image/')) { + imageUrl = enclosure.getAttribute('url'); + } + + // Opprett artikkel-element + const articleElement = document.createElement('div'); + articleElement.className = 'article'; + + // Legg til bilde hvis tilgjengelig + let imageHtml = ''; + if (imageUrl) { + imageHtml = `
${title}
`; + } + + articleElement.innerHTML = ` +

${title}

+ + ${imageHtml} +
${stripHtml(description).substring(0, 150)}...
+ `; + + container.appendChild(articleElement); + } + + } catch (error) { + console.error('Feil ved henting av RSS feed:', error); + container.innerHTML = `
+

Kunne ikke laste inn artikler.

+

Feilmelding: ${error.message}

+

Prøv å oppdatere siden eller sjekk nettverkstilkoblingen din.

+
`; + + // Logg mer detaljert feilinformasjon til konsollen for debugging + if (error.stack) { + console.error('Stack trace:', error.stack); + } + } + } + + // Hjelpefunksjon for å fjerne HTML-tags fra tekst + function stripHtml(html) { + const temp = document.createElement('div'); + temp.innerHTML = html; + return temp.textContent || temp.innerText || ''; + } + + // Hjelpefunksjon for å forsøke å hente RSS med retry + async function fetchWithRetry(url, container, maxRetries = 2) { + let retryCount = 0; + let lastError; + + while (retryCount <= maxRetries) { + try { + if (retryCount > 0) { + console.log(`Forsøker på nytt (${retryCount}/${maxRetries}) for ${url}`); + // Vis melding om at vi prøver på nytt + container.innerHTML = `
Forsøker på nytt (${retryCount}/${maxRetries})...
`; + // Vent litt før neste forsøk + await new Promise(resolve => setTimeout(resolve, 1500)); + } + + await fetchRSSFeed(url, container); + return; // Vellykket, avslutt retry-løkken + } catch (error) { + lastError = error; + console.warn(`Forsøk ${retryCount + 1}/${maxRetries + 1} feilet for ${url}:`, error.message); + retryCount++; + } + } + + // Hvis vi kommer hit, har alle forsøk feilet + console.error(`Alle forsøk feilet for ${url}:`, lastError); + container.innerHTML = `
+

Kunne ikke laste inn artikler etter flere forsøk.

+

Feilmelding: ${lastError.message}

+

Prøv å oppdatere siden eller sjekk nettverkstilkoblingen din.

+
`; + } + + // Hent artikler fra begge kilder med retry-mekanisme + fetchWithRetry(itavisenRSSUrl, itavisenArticlesContainer); + fetchWithRetry(teknoRSSUrl, teknoArticlesContainer); + + // Legg til knapp for å oppdatere feeds + const header = document.querySelector('header'); + const refreshButton = document.createElement('button'); + refreshButton.textContent = 'Oppdater nyheter'; + refreshButton.className = 'refresh-button'; + refreshButton.addEventListener('click', function() { + // Vis lasteindikatorer igjen + itavisenArticlesContainer.innerHTML = '
Laster inn artikler...
'; + teknoArticlesContainer.innerHTML = '
Laster inn artikler...
'; + + // Hent artikler på nytt + fetchRSSFeed(itavisenRSSUrl, itavisenArticlesContainer); + fetchRSSFeed(teknoRSSUrl, teknoArticlesContainer); + }); + + header.appendChild(refreshButton); + + // Legg til stil for oppdateringsknappen + const style = document.createElement('style'); + style.textContent = ` + .refresh-button { + background-color: #3498db; + color: white; + border: none; + padding: 10px 15px; + border-radius: 4px; + cursor: pointer; + font-size: 14px; + margin-top: 15px; + transition: background-color 0.3s; + } + + .refresh-button:hover { + background-color: #2980b9; + } + `; + document.head.appendChild(style); +});