PROJET AUTOBLOG


Warrior du Dimanche

Site original : Warrior du Dimanche

⇐ retour index

Javascript: tester la validité des liens d'une page afin de les styler

vendredi 27 janvier 2023 à 10:45

Petit bout de code fait à la va-vite dans le but de vérifier la validité des liens d'une page. Mon objectif est de pouvoir à terme montrer automatiquement les liens ne répondant plus sur la page où je regroupe les liens de téléchargement illégal

Le bout de code actuel

Dans le code ci-dessous, j'utilise fetch et les promesses pour lancer des requêtes afin de styler les liens testés:

function checkLinks(nodelist){
    function checkUrl(link){
        return fetch(link).then(function(response){     
            return response.status;
        }).catch(function(error){
            return error.status;
        });
    }
    if (!nodelist){
        checkLinks(document.querySelectorAll('.checkLink'));
        return;
    }
    for (let obj of nodelist){
        if (obj.tagName=="A"){
            checkUrl(obj.href).then(function(response){obj.classList.add("status"+response);});
        }else if (obj.hasAttribute("src")){
            checkUrl(obj.src).then(function(response){obj.classList.add("status"+response);});
        }else{
            checkLinks(obj.querySelectorAll("*[href],*[src]"));
        }
    }
}
checkLinks();

Explication rapide

Étape 1

J'ai d'abord fait une fonction qui appelle une URL et renvoie une promesse qui, une fois résolue, renverra le statut de la requête. On y retrouve .then qui renvoie le statut d'une requête qui aboutit et .catch qui renvoie celui d'une requête se soldant par une erreur.

function checkUrl(link){
        return fetch(link).then(function(response){     
            return response.status;
        }).catch(function(error){
            return error.status;
        });
    }

Les plus coquinous d'entre-vous me feront remarquer à juste titre que, vu ce que je renvoie, je pouvais me contenter de

function checkUrl(link){
        return fetch(link).then(function(response){     
            return response.status;
        });
    }

Ceci dit, en prévoyant les deux cas, je m'autorise à gérer le retour différemment selon si ça aboutit ou pas (par exemple retourner «ok200» ou «error404»

Étape 2:

Ce block n'est là que pour simplifier la vie de l'utilisateur en lui évitant de procéder lui-même au querySelectorAll()

if (!nodelist){
        checkLinks(document.querySelectorAll('.checkLink'));
        return;
    }

Étape 3:

Je parcours la nodeList en vérifiant l'URL passée en href (pour les A) ou en src (pour les img par exemple).

Le dernier cas est celui où l'on souhaite vérifier les liens contenus dans un div portant la classe .checkLink : il suffit d'appeler la même fonction de façon récursive en lui fournissant le nodeList des liens contenus das le DIV en question. (ça permet de vérifier un grand nombre de liens sans avoir à leur ajouter individuellement la classe .checkLink, ce qui est particulièrement utile quand on publie des articles en utilisant markdown )

for (let obj of nodelist){
        if (obj.tagName=="A"){
            checkUrl(obj.href).then(function(response){obj.classList.add("status"+response);});
        }else if (obj.hasAttribute("src")){
            checkUrl(obj.src).then(function(response){obj.classList.add("status"+response);});
        }else{
            checkLinks(obj.querySelectorAll("a,img"));
        }
    }

Comment on l'utilise ?

Il suffit de mettre la classe .checkLink à tout objet dont on veut tester les liens et de coller la fonction dans la page puis de l'appeler via un checkLinks(); de bon aloi.

En l'état, la fonction ajoutera une classe .status200 pour les liens ok ou .status404 pour les URL qui ne répondent plus.

Il ne reste plus qu'à styler ces classes en changeant la couleur, le fond ou en ajoutant des emoji avec un petit content. On peut même éventuellement masquer un objet dont l'URL ne répond pas...

Limites

Le script étant en JS, il se heurte évidemment aux règles de la politique CORS: toute requête hors du domaine en cours va échouer à moins de redéfinir le CORS dans le Head de la page via

<meta http-equiv="Content-Security-Policy" content="Content-Security-Policy:..."/>

Licence

Comme d'habitude, il s'agit autant d'un proof of concept que d'une truc utile... en tout cas, n'hésitez pas à en faire rigoureusement ce que vous voulez: c'est cadeau...

<link rel="stylesheet" href="http://www.warriordudimanche.net/./plugins/Galart/style.css"/> <link rel="stylesheet" href="http://www.warriordudimanche.net/./plugins/Galart/assets/lightbox.css"/> <script src="http://www.warriordudimanche.net/./plugins/Galart/assets/lightbox.js"> <script>[].forEach.call(document.querySelectorAll("[lightbox]"), function(el) { el.lightbox = new Lightbox(el);});

► Commentaires