This commit is contained in:
parent
738c49a4f0
commit
657fe6b1b7
2 changed files with 272 additions and 0 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
272
test/script.js
Normal file
272
test/script.js
Normal file
|
@ -0,0 +1,272 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Elementer for å vise artikler
|
||||
const itavisenArticlesContainer = document.getElementById('itavisen-articles');
|
||||
const teknoArticlesContainer = document.getElementById('tekno-articles');
|
||||
|
||||
// CORS Proxyer for å omgå CORS-begrensninger
|
||||
const corsProxies = [
|
||||
'https://corsproxy.io/?',
|
||||
'https://cors-anywhere.herokuapp.com/',
|
||||
'https://api.codetabs.com/v1/proxy/?quest=',
|
||||
'https://api.allorigins.win/raw?url='
|
||||
];
|
||||
let currentProxyIndex = 0;
|
||||
const corsProxy = corsProxies[currentProxyIndex];
|
||||
|
||||
// RSS-feed URLs
|
||||
const itavisenRSSUrl = 'https://itavisen.no/feed/';
|
||||
const teknoRSSUrl = 'https://www.tek.no/feed/'; // Oppdatert til korrekt RSS-feed URL for Tek.no
|
||||
|
||||
// Vis lasteindikatorer
|
||||
itavisenArticlesContainer.innerHTML = '<div class="loading">Laster inn artikler...</div>';
|
||||
teknoArticlesContainer.innerHTML = '<div class="loading">Laster inn artikler...</div>';
|
||||
|
||||
// Funksjon for å hente og parse RSS-feed
|
||||
// Funksjon for å prøve alternative proxyer hvis den første feiler
|
||||
async function fetchWithFallbackProxy(url) {
|
||||
let lastError;
|
||||
|
||||
// Prøv hver proxy i rekkefølge
|
||||
for (let i = 0; i < corsProxies.length; i++) {
|
||||
try {
|
||||
const proxyUrl = corsProxies[i] + encodeURIComponent(url);
|
||||
console.log(`Forsøker proxy ${i+1}/${corsProxies.length}: ${corsProxies[i]}`);
|
||||
|
||||
// Legg til timeout for å unngå at forespørselen henger for lenge
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => 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 = '<div class="error-message">Ingen artikler funnet i RSS-feeden.</div>';
|
||||
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*<!\[CDATA\[\s*|\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*<!\[CDATA\[\s*|\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 = `<div class="article-image"><img src="${imageUrl}" alt="${title}" /></div>`;
|
||||
}
|
||||
|
||||
articleElement.innerHTML = `
|
||||
<h3><a href="${link}" target="_blank">${title}</a></h3>
|
||||
<div class="article-meta">${formattedDate}</div>
|
||||
${imageHtml}
|
||||
<div class="article-description">${stripHtml(description).substring(0, 150)}...</div>
|
||||
`;
|
||||
|
||||
container.appendChild(articleElement);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Feil ved henting av RSS feed:', error);
|
||||
container.innerHTML = `<div class="error-message">
|
||||
<p>Kunne ikke laste inn artikler.</p>
|
||||
<p>Feilmelding: ${error.message}</p>
|
||||
<p>Prøv å oppdatere siden eller sjekk nettverkstilkoblingen din.</p>
|
||||
</div>`;
|
||||
|
||||
// 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 = `<div class="loading">Forsøker på nytt (${retryCount}/${maxRetries})...</div>`;
|
||||
// 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 = `<div class="error-message">
|
||||
<p>Kunne ikke laste inn artikler etter flere forsøk.</p>
|
||||
<p>Feilmelding: ${lastError.message}</p>
|
||||
<p>Prøv å oppdatere siden eller sjekk nettverkstilkoblingen din.</p>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// 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 = '<div class="loading">Laster inn artikler...</div>';
|
||||
teknoArticlesContainer.innerHTML = '<div class="loading">Laster inn artikler...</div>';
|
||||
|
||||
// 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);
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue