ページ内のリンクでリンク切れを起こしているエレメントを自動判別するスニペット

2018年2月20日

HTML Javascript PHP テクノロジー プログラミング

WEBページを作って運用する時に、CMSのツールを使っていると、サイト内部のリンク切れは、自動で処理されて表示されないようにしてくれる機能があるけど、 外部サイトのURLをリンクした時に、そのリンク先がなくなっている場合などは、リンククリックしたユーザーが残念な思いをするだけです。 昔からリンク切れ検知ツールっていくつもあるけど、リアルタイムクローリングしているようなサイトじゃないと最近はあまり見かけなくなりました。 とりあえず、簡単なソースコードでツール化してみたので、使いたい人はお試しあれ。

機能概要

外部リンク表示

サイト内リンクは、そのままで、外部リンクは、外部リンクアイコンを表示。 表示しているURLとリンク先のhostnameを判定してます。

リンク切れ表示

レスポンスステータスが「200」番以外は、リンク切れ判定にしてます。 ローカルPHPで処理してます。 javascriptでは、クロスドメイン制約がありどうしても突破できないので、ローカルphpを一つ設置する方式にしてます。

ソースコード

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"/> <title>check-broken-links</title> <script type="text/javascript" src="checkBrokenLink.js"></script> </head> <body> <ol> <li><a href="index.html">index.html</a></li> <li><a href="http://hoge.yahoo.co">http://hoge.yahoo.co.jp</a></li> <li><a href="https://github.com/">https://github.com/</a></li> <li><a href="hoge.html">nothing link</a></li> <li><a href="img.html"><img src="img/sample.jpg"></a></li> </ol> </body> </html> /** * check broken link * 2018.2.16 Koji.Yugeta * [Summery] * * [Usage] * */ ;(function(){ var $$ = function(){ window.addEventListener("load",$$.prototype.start); }; $$.prototype.start = function(){ $$.prototype.setStyle(); var links = document.links; for(var i=0; i<links.length; i++){ if(location.hostname !== links[i].hostname){ links[i].className += " external-link"; links[i].target = "_blank"; var url = "//"+location.hostname+location.pathname+"checkBrokenLink.php?url="+links[i].href; new $$ajax({ url:url, data:{ elm:links[i] }, method:"get", onSuccess:function(res){ if(res.responseText === "200"){console.log("-"); // console.log(res.responseText); } else if(res.responseText === ""){console.log("+"); this.data.elm.className += " broken-link"; } }, onError:function(event){ this.data.elm.className += " broken-link"; } }); } else{ var url = links[i].href; new $$ajax({ url:url, data:{ elm:links[i] }, method:"get", onError:function(event){ this.data.elm.className += " broken-link"; } }); } } // var sc = document.getElementById("test"); // console.log(sc); }; $$.prototype.setStyle = function(){ var css = ""; css += ".external-link{"+"\n"; css += " display:inline-block;"; css += "}"+"\n"; css += ".external-link:after{"; css += " content:'';"; css += " display:inline-block;"; css += " height:16px;"; css += " width :16px;"; css += " vertical-align :middle;"; css += " padding-left:8px;"; css += " background-image: url('img/external-link.svg');"; css += " background-size: 100% 100%;"; css += "}"; css += ".broken-link{"+"\n"; css += " display:inline-block;"; css += "}"+"\n"; css += ".broken-link:after{"; css += " content:'';"; css += " display:inline-block;"; css += " min-height:14px;"; css += " max-height:24px;"; css += " height:100%;"; css += " width :16px;"; css += " background-image: url('img/caution.svg');"; css += " background-size: 100% 100%;"; css += " vertical-align :middle;"; css += " padding-left:8px;"; css += "}"; var style = document.createElement("style"); style.innerHTML = css; document.getElementsByTagName("head")[0].appendChild(style); }; var $$ajax = function(options){ if(!options){return} var ajax = new $$ajax; var httpoj = $$ajax.prototype.createHttpRequest(); if(!httpoj){return;} // open メソッド; var option = ajax.setOption(options); // 実行 httpoj.open( option.method , option.url , option.async ); // type httpoj.setRequestHeader('Content-Type', option.type); // onload-check httpoj.onreadystatechange = function(){ //readyState値は4で受信完了 (2は受信途中) if (this.readyState == "4"){ // 受信成功 if(this.status == "200"){ option.onSuccess(this); } // ページエラー else if(this.status == "404"){ option.onError(this); } // それ以外 else{ option.onStatus(this); } } }; //query整形 var data = ajax.setQuery(option); //send メソッド if(data.length){ httpoj.send(data.join("&")); } else{ httpoj.send(); } }; $$ajax.prototype.dataOption = { url:"", query:{}, // same-key Nothing querys:[], // same-key OK data:{}, // ETC-data event受渡用 async:"true", // [trye:非同期 false:同期] method:"POST", // [POST / GET] type:"application/x-www-form-urlencoded", // [text/javascript]... onSuccess:function(res){}, onStatus:function(res){}, onError:function(res){} }; $$ajax.prototype.option = {}; $$ajax.prototype.createHttpRequest = function(){ //Win ie用 if(window.ActiveXObject){ //MSXML2以降用; try{return new ActiveXObject("Msxml2.XMLHTTP")} catch(e){ //旧MSXML用; try{return new ActiveXObject("Microsoft.XMLHTTP")} catch(e2){return null} } } //Win ie以外のXMLHttpRequestオブジェクト実装ブラウザ用; else if(window.XMLHttpRequest){return new XMLHttpRequest()} else{return null} }; $$ajax.prototype.setOption = function(options){ var option = {}; for(var i in this.dataOption){ if(typeof options[i] != "undefined"){ option[i] = options[i]; } else{ option[i] = this.dataOption[i]; } } return option; }; $$ajax.prototype.setQuery = function(option){ var data = []; if(typeof option.query != "undefined"){ for(var i in option.query){ data.push(i+"="+encodeURIComponent(option.query[i])); } } if(typeof option.querys != "undefined"){ for(var i=0;i<option.querys.length;i++){ if(typeof option.querys[i] == "Array"){ data.push(option.querys[i][0]+"="+encodeURIComponent(option.querys[i][1])); } else{ var sp = option.querys[i].split("="); data.push(sp[0]+"="+encodeURIComponent(sp[1])); } } } return data; }; new $$; })(); <?php if(isset($_REQUEST["url"])){ $res = get_headers($_REQUEST["url"],1); echo trim(str_replace("OK","",$res["Status"])); }

その他画像など

※画像は、FREEの物を適当にDLしてお使いください。 icon finder

画面イメージ

今回は、少し手抜きをして、デモページを作っていません。 画像で勘弁ください。 リンク切れと、外部リンクの右側に、アイコンが表示されているのが分かりますか? 最近こうした気の利いたUIのサイトもたま〜に見かけるようになりましたが、こうした小さなおもてなしができるWEBサイトが、知らない間に使いやすいサイトという事なんでしょうね。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ